Skip to main content
spelling error
Link
mathmaniage
  • 595
  • 2
  • 6
  • 23

Hoe How to make a property appear in more than one mode?

added 9720 characters in body
Source Link
mathmaniage
  • 595
  • 2
  • 6
  • 23

EDIT: I'm setting up a panel for rigging, here's the full code:

import bpy

CUSTOM_CATEGORY = 'RIG OPTIONS'

class RigUI(bpy.types.Panel):
    bl_idname = 'POSE_PT_RigUI'
    bl_label = "Rig Controls"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    bl_context = "posemode"
    bl_category = CUSTOM_CATEGORY
    
    #bones in use
    head = "head"
    neck = "neck_bone"
    
    hip = "hip"
    rib = "rib"
    
    
    shoulder_L = "shoulder.L"
    upper_arm_FK_L = "upper_arm_FK.L"
    forearm_FK_L = "forearm_FK.L"
    hand_FK_L = "hand_FK.L"
    
    
    shoulder_R = "shoulder.R"
    upper_arm_FK_R = "upper_arm_FK.R"
    forearm_FK_R= "forearm_FK.R"
    hand_FK_R = "hand_FK.R"
    
    
    thigh_FK_L = "thigh_FK.L"
    shin_FK_L = "shin_FK.L"
    foot_FK_L = "foot_FK.L"
    toe_FK_L = "toe_FK.L"
    
    
    thigh_FK_R = "thigh_FK.R"
    shin_FK_R = "shin_FK.R"
    foot_FK_R = "foot_FK.R"
    toe_FK_R= "toe_FK.R"
    
    elbow_pole_IK_L = "elbow_pole.L"
    hand_IK_L = "hand_IK.L"
    forearm_viz_IK_L = "forearm_viz.L"
    
    
    elbow_pole_IK_R = "elbow_pole.R"
    hand_IK_R = "hand_IK.R"
    forearm_viz_IK_R = "forearm_viz.R"
    
    knee_pole_IK_L = "knee_pole.L"
    knee_viz_IK_L = "knee_viz.L"
    foot_IK_L = "foot_IK.L"
    
    knee_pole_IK_R = "knee_pole.R"
    knee_viz_IK_R = "knee_viz.R"
    foot_IK_R = "foot_IK.R"
    
    
    
    #group bone for convienience
    groups = {
                'isolate_head' : ['head', head, neck],
                'isolated_torso': ['rib', hip, rib],
                
                'pivot_slide' : ['hip', hip, rib],
                
                'isolate_left_arm' : ['upper_arm_FK.L', upper_arm_FK_L, forearm_FK_L, hand_FK_L, shoulder_L],
                'isolate_right_arm' : ['upper_arm_FK.R',upper_arm_FK_R, forearm_FK_R, hand_FK_R, shoulder_R],
                
                'isolate_left_leg' : ['thigh_FK.L', thigh_FK_L, shin_FK_L, foot_FK_L, toe_FK_L],
                'isolate_right_leg' : ['thigh_FK.R', thigh_FK_R, shin_FK_R, foot_FK_R, toe_FK_R],
                
                'switch_IK/FK_left_arm' :['hand_IK.L', elbow_pole_IK_L, hand_IK_L, forearm_viz_IK_L, upper_arm_FK_L, forearm_FK_L, hand_FK_L],    
                'switch_IK/FK_right_arm' : ['hand_IK.R', elbow_pole_IK_R, hand_IK_R, forearm_viz_IK_R, upper_arm_FK_R, forearm_FK_R, hand_FK_R],
                
                                
                'switch_IK/FK_left_leg' : ['foot_IK.L', knee_pole_IK_L, knee_viz_IK_L, foot_IK_L,thigh_FK_L, shin_FK_L, foot_FK_L, toe_FK_L],
                'switch_IK/FK_right_leg' : ['foot_IK.R', knee_pole_IK_R, knee_viz_IK_R, foot_IK_R, thigh_FK_R, shin_FK_R, foot_FK_R, toe_FK_R],
              }
    
    #print("READING VARIABLES")    
    

    
    def is_selected(self, names, selected_bones):
        """Returns whether any of the named bones are selected"""
        if type(names) == list:
            for name in names:
                if name in selected_bones:
                    return True
        elif names in selected_bones:
            return True
        return False
        
                

    def draw(self, context):
        layout = self.layout
        #row = layout.row()
        
        pose_bones = context.active_object.pose.bones
        #this excetion handler is redundant
        try:
            selected_bones = [bone.name for bone in context.selected_pose_bones]
            if context.active_pose_bone not in selected_bones: selected_bones.append(context.active_pose_bone.name)
        except(AttributeError, TypeError):
            return
        
        
        layout.prop(context.scene, "global_view")
        #print("The context type is: ", type(context))
        
        #print("In draw function")
        if context.scene.global_view:
            for property in self.groups.keys():
                bone_assoc = self.groups[property][0]
                required_prop = '["{}"]'.format(property)
                
            
                layout.prop(pose_bones[bone_assoc], required_prop, slider=True)
            
            #print("bpy.types.Scene.global_view", bpy.types.Scene.global_view, type(bpy.types.Scene.global_view))
            



        else:
            for property in self.groups.keys():
                cur_bones = self.groups[property][1:]
                bone_assoc = self.groups[property][0]
                required_prop = '["{}"]'.format(property)
                
                if self.is_selected(cur_bones, selected_bones):
                    layout.prop(pose_bones[bone_assoc], required_prop, slider=True)
                
                #print('in second view')
                
            
                
                            
                            
                            

class RigLayers(bpy.types.Panel):
    bl_idname = 'POSE_PT_RigLayers'
    bl_label = "Rig Layers"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    bl_context = "posemode"
    bl_category = CUSTOM_CATEGORY
    
    bone_groups ={
                
                'Root bone': 0,
                'FK bones': 1,
                'IK bones': 2,
                'Facial bones':3,
                'Manual spine':14
    }
    
    #control_layers = [0,1,2,3,14]
    #total_layers = 32

    
    
#    def dctv_other_pose_lyr(self, bone_layer):
#        """deactivate layers except bone_layer"""
#        for i in range(0,self.total_layers):
#            if i!=bone_layer:
#                bpy.context.object.data.layers[i] = False
#                
        
            
        
    
    def draw(self, context):
        column = self.layout.column() #items are placed under each other in a column
        
        #column.prop(context.scene, "switch_mode")
        contexts = []
        #if context.scene.switch_mode==False:
        for item in self.bone_groups.keys():

            column.prop(context.active_object.data, 'layers',
             index=self.bone_groups[item],
             toggle=True, text=item, 
             emboss=True)
             
        

#        else:
#            for item in self.bone_groups.keys():
#                column.prop(context.active_object.data, 'layers',
#                 index=self.bone_groups[item],
#                 event = lambda item: self.dctv_other_pose_lyr(self.bone_groups[item]),
#                  toggle=True, text=item)
        
                


class facial_exp(bpy.types.Panel):
    
    bl_idname = 'FACE_PT_RigUI'
    bl_label = "Facial controls"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    bl_context = "posemode"
    bl_category = CUSTOM_CATEGORY
    
    def draw(self, context):
        pose_bones = context.active_object.pose.bones
        layout=self.layout
        layout.prop(pose_bones["eyebrow.L"], '["angry.L"]', slider=True)
        layout.prop(pose_bones["eyebrow.L"], '["sad.L"]', slider=True)
        layout.prop(pose_bones["eyebrow.L"], '["surprise.L"]', slider=True)
        layout.label(text=" ")
        layout.prop(pose_bones["eyebrow.R"], '["angry.R"]', slider=True)
        layout.prop(pose_bones["eyebrow.R"], '["sad.R"]', slider=True)
        layout.prop(pose_bones["eyebrow.R"], '["surprise.R"]', slider=True)
        
        
        
    
        
        
def register():
    bpy.types.Scene.global_view = bpy.props.BoolProperty(
                                    name = "Toggle Global View",
                                    description = "toggles all sliders irrespective of selection",
                                    default = True)
    
    #TO-DO
#    bpy.types.Scene.switch_mode = bpy.props.BoolProperty(
#                                    name = "Toggle Switch Mode",
#                                    description = "toggles A radio button behaviour",
#                                    default = False)
    bpy.utils.register_class(RigUI)
    bpy.utils.register_class(RigLayers)
    bpy.utils.register_class(facial_exp)





register()  

Now, this generates a panel, somewhat like this:

nice panel

Now, everything's nice and handy but, I want the "Facial Control" panel to appear both in posemode, edit mode, object mode and sculpt mode, and as you have seen in the code, this to my knowledge is controlled by the bl_context parameter, but, if the panel is to appear in all these modes, what should I set the bl_context parameter to?

EDIT: I'm setting up a panel for rigging, here's the full code:

import bpy

CUSTOM_CATEGORY = 'RIG OPTIONS'

class RigUI(bpy.types.Panel):
    bl_idname = 'POSE_PT_RigUI'
    bl_label = "Rig Controls"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    bl_context = "posemode"
    bl_category = CUSTOM_CATEGORY
    
    #bones in use
    head = "head"
    neck = "neck_bone"
    
    hip = "hip"
    rib = "rib"
    
    
    shoulder_L = "shoulder.L"
    upper_arm_FK_L = "upper_arm_FK.L"
    forearm_FK_L = "forearm_FK.L"
    hand_FK_L = "hand_FK.L"
    
    
    shoulder_R = "shoulder.R"
    upper_arm_FK_R = "upper_arm_FK.R"
    forearm_FK_R= "forearm_FK.R"
    hand_FK_R = "hand_FK.R"
    
    
    thigh_FK_L = "thigh_FK.L"
    shin_FK_L = "shin_FK.L"
    foot_FK_L = "foot_FK.L"
    toe_FK_L = "toe_FK.L"
    
    
    thigh_FK_R = "thigh_FK.R"
    shin_FK_R = "shin_FK.R"
    foot_FK_R = "foot_FK.R"
    toe_FK_R= "toe_FK.R"
    
    elbow_pole_IK_L = "elbow_pole.L"
    hand_IK_L = "hand_IK.L"
    forearm_viz_IK_L = "forearm_viz.L"
    
    
    elbow_pole_IK_R = "elbow_pole.R"
    hand_IK_R = "hand_IK.R"
    forearm_viz_IK_R = "forearm_viz.R"
    
    knee_pole_IK_L = "knee_pole.L"
    knee_viz_IK_L = "knee_viz.L"
    foot_IK_L = "foot_IK.L"
    
    knee_pole_IK_R = "knee_pole.R"
    knee_viz_IK_R = "knee_viz.R"
    foot_IK_R = "foot_IK.R"
    
    
    
    #group bone for convienience
    groups = {
                'isolate_head' : ['head', head, neck],
                'isolated_torso': ['rib', hip, rib],
                
                'pivot_slide' : ['hip', hip, rib],
                
                'isolate_left_arm' : ['upper_arm_FK.L', upper_arm_FK_L, forearm_FK_L, hand_FK_L, shoulder_L],
                'isolate_right_arm' : ['upper_arm_FK.R',upper_arm_FK_R, forearm_FK_R, hand_FK_R, shoulder_R],
                
                'isolate_left_leg' : ['thigh_FK.L', thigh_FK_L, shin_FK_L, foot_FK_L, toe_FK_L],
                'isolate_right_leg' : ['thigh_FK.R', thigh_FK_R, shin_FK_R, foot_FK_R, toe_FK_R],
                
                'switch_IK/FK_left_arm' :['hand_IK.L', elbow_pole_IK_L, hand_IK_L, forearm_viz_IK_L, upper_arm_FK_L, forearm_FK_L, hand_FK_L],    
                'switch_IK/FK_right_arm' : ['hand_IK.R', elbow_pole_IK_R, hand_IK_R, forearm_viz_IK_R, upper_arm_FK_R, forearm_FK_R, hand_FK_R],
                
                                
                'switch_IK/FK_left_leg' : ['foot_IK.L', knee_pole_IK_L, knee_viz_IK_L, foot_IK_L,thigh_FK_L, shin_FK_L, foot_FK_L, toe_FK_L],
                'switch_IK/FK_right_leg' : ['foot_IK.R', knee_pole_IK_R, knee_viz_IK_R, foot_IK_R, thigh_FK_R, shin_FK_R, foot_FK_R, toe_FK_R],
              }
    
    #print("READING VARIABLES")    
    

    
    def is_selected(self, names, selected_bones):
        """Returns whether any of the named bones are selected"""
        if type(names) == list:
            for name in names:
                if name in selected_bones:
                    return True
        elif names in selected_bones:
            return True
        return False
        
                

    def draw(self, context):
        layout = self.layout
        #row = layout.row()
        
        pose_bones = context.active_object.pose.bones
        #this excetion handler is redundant
        try:
            selected_bones = [bone.name for bone in context.selected_pose_bones]
            if context.active_pose_bone not in selected_bones: selected_bones.append(context.active_pose_bone.name)
        except(AttributeError, TypeError):
            return
        
        
        layout.prop(context.scene, "global_view")
        #print("The context type is: ", type(context))
        
        #print("In draw function")
        if context.scene.global_view:
            for property in self.groups.keys():
                bone_assoc = self.groups[property][0]
                required_prop = '["{}"]'.format(property)
                
            
                layout.prop(pose_bones[bone_assoc], required_prop, slider=True)
            
            #print("bpy.types.Scene.global_view", bpy.types.Scene.global_view, type(bpy.types.Scene.global_view))
            



        else:
            for property in self.groups.keys():
                cur_bones = self.groups[property][1:]
                bone_assoc = self.groups[property][0]
                required_prop = '["{}"]'.format(property)
                
                if self.is_selected(cur_bones, selected_bones):
                    layout.prop(pose_bones[bone_assoc], required_prop, slider=True)
                
                #print('in second view')
                
            
                
                            
                            
                            

class RigLayers(bpy.types.Panel):
    bl_idname = 'POSE_PT_RigLayers'
    bl_label = "Rig Layers"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    bl_context = "posemode"
    bl_category = CUSTOM_CATEGORY
    
    bone_groups ={
                
                'Root bone': 0,
                'FK bones': 1,
                'IK bones': 2,
                'Facial bones':3,
                'Manual spine':14
    }
    
    #control_layers = [0,1,2,3,14]
    #total_layers = 32

    
    
#    def dctv_other_pose_lyr(self, bone_layer):
#        """deactivate layers except bone_layer"""
#        for i in range(0,self.total_layers):
#            if i!=bone_layer:
#                bpy.context.object.data.layers[i] = False
#                
        
            
        
    
    def draw(self, context):
        column = self.layout.column() #items are placed under each other in a column
        
        #column.prop(context.scene, "switch_mode")
        contexts = []
        #if context.scene.switch_mode==False:
        for item in self.bone_groups.keys():

            column.prop(context.active_object.data, 'layers',
             index=self.bone_groups[item],
             toggle=True, text=item, 
             emboss=True)
             
        

#        else:
#            for item in self.bone_groups.keys():
#                column.prop(context.active_object.data, 'layers',
#                 index=self.bone_groups[item],
#                 event = lambda item: self.dctv_other_pose_lyr(self.bone_groups[item]),
#                  toggle=True, text=item)
        
                


class facial_exp(bpy.types.Panel):
    
    bl_idname = 'FACE_PT_RigUI'
    bl_label = "Facial controls"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    bl_context = "posemode"
    bl_category = CUSTOM_CATEGORY
    
    def draw(self, context):
        pose_bones = context.active_object.pose.bones
        layout=self.layout
        layout.prop(pose_bones["eyebrow.L"], '["angry.L"]', slider=True)
        layout.prop(pose_bones["eyebrow.L"], '["sad.L"]', slider=True)
        layout.prop(pose_bones["eyebrow.L"], '["surprise.L"]', slider=True)
        layout.label(text=" ")
        layout.prop(pose_bones["eyebrow.R"], '["angry.R"]', slider=True)
        layout.prop(pose_bones["eyebrow.R"], '["sad.R"]', slider=True)
        layout.prop(pose_bones["eyebrow.R"], '["surprise.R"]', slider=True)
        
        
        
    
        
        
def register():
    bpy.types.Scene.global_view = bpy.props.BoolProperty(
                                    name = "Toggle Global View",
                                    description = "toggles all sliders irrespective of selection",
                                    default = True)
    
    #TO-DO
#    bpy.types.Scene.switch_mode = bpy.props.BoolProperty(
#                                    name = "Toggle Switch Mode",
#                                    description = "toggles A radio button behaviour",
#                                    default = False)
    bpy.utils.register_class(RigUI)
    bpy.utils.register_class(RigLayers)
    bpy.utils.register_class(facial_exp)





register()  

Now, this generates a panel, somewhat like this:

nice panel

Now, everything's nice and handy but, I want the "Facial Control" panel to appear both in posemode, edit mode, object mode and sculpt mode, and as you have seen in the code, this to my knowledge is controlled by the bl_context parameter, but, if the panel is to appear in all these modes, what should I set the bl_context parameter to?

edited body; edited title
Source Link
Martynas Žiemys
  • 28.1k
  • 2
  • 38
  • 81

making Hoe to make a property appear in more than one mode?

theThe bl_context class variable defines what mode the drawn property appears in, e.g. bl_context=posemode makes whatever drawn via the draw method appear only in the pose mode. What if we want the property to appear in both objectmode and posemode, and what are the values for other modes, like: particle edit mode, vertex paint mode, sculpt mode?

making a property appear in more than one mode

the bl_context class variable defines what mode the drawn property appears in, e.g. bl_context=posemode makes whatever drawn via the draw method appear only in the pose mode. What if we want the property to appear in both objectmode and posemode, and what are the values for other modes, like: particle edit mode, vertex paint mode, sculpt mode?

Hoe to make a property appear in more than one mode?

The bl_context class variable defines what mode the drawn property appears in, e.g. bl_context=posemode makes whatever drawn via the draw method appear only in the pose mode. What if we want the property to appear in both objectmode and posemode, and what are the values for other modes, like: particle edit mode, vertex paint mode, sculpt mode?

Source Link
mathmaniage
  • 595
  • 2
  • 6
  • 23
Loading