* added an armature submenu where python defined armatures can go.
* bpy.utils.display_name(), which makes filenames and module names look nicer in menus eg... /home/me/foo_bar.py --> "Foo Bar" * missing rna_path --> data_path renaming
This commit is contained in:
		@@ -53,6 +53,23 @@ def clean_name(name, replace="_"):
 | 
			
		||||
        name = name.replace(ch,  replace)
 | 
			
		||||
    return name
 | 
			
		||||
 | 
			
		||||
def display_name(name):
 | 
			
		||||
    '''
 | 
			
		||||
    Only capitalize all lowercase names, mixed case use them as is.
 | 
			
		||||
    should work with filenames and module names.
 | 
			
		||||
    '''
 | 
			
		||||
    name_base = os.path.splitext(name)[0]
 | 
			
		||||
 | 
			
		||||
    # string replacements
 | 
			
		||||
    name_base = name_base.replace("_colon_", ":")
 | 
			
		||||
 | 
			
		||||
    name_base = name_base.replace("_", " ")
 | 
			
		||||
 | 
			
		||||
    if name_base.lower() == name_base:
 | 
			
		||||
        return ' '.join([w[0].upper() + w[1:] for w in name_base.split()])
 | 
			
		||||
    else:
 | 
			
		||||
        return name_base
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# base scripts
 | 
			
		||||
_scripts = os.path.join(os.path.dirname(__file__), os.path.pardir, os.path.pardir)
 | 
			
		||||
 
 | 
			
		||||
@@ -288,21 +288,7 @@ class Menu(StructRNA):
 | 
			
		||||
        # hard coded to set the operators 'path' to the filename.
 | 
			
		||||
 | 
			
		||||
        import os
 | 
			
		||||
 | 
			
		||||
        def path_to_name(f):
 | 
			
		||||
            ''' Only capitalize all lowercase names, mixed case use them as is.
 | 
			
		||||
            '''
 | 
			
		||||
            f_base = os.path.splitext(f)[0]
 | 
			
		||||
 | 
			
		||||
            # string replacements
 | 
			
		||||
            f_base = f_base.replace("_colon_", ":")
 | 
			
		||||
 | 
			
		||||
            f_base = f_base.replace("_", " ")
 | 
			
		||||
 | 
			
		||||
            if f_base.lower() == f_base:
 | 
			
		||||
                return ' '.join([w[0].upper() + w[1:] for w in f_base.split()])
 | 
			
		||||
            else:
 | 
			
		||||
                return f_base
 | 
			
		||||
        import bpy.utils
 | 
			
		||||
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
 | 
			
		||||
@@ -318,7 +304,7 @@ class Menu(StructRNA):
 | 
			
		||||
            if f.startswith("."):
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            layout.operator(operator, text=path_to_name(f)).path = path
 | 
			
		||||
            layout.operator(operator, text=bpy.utils.display_name(f)).path = path
 | 
			
		||||
 | 
			
		||||
    def draw_preset(self, context):
 | 
			
		||||
        '''Define these on the subclass
 | 
			
		||||
 
 | 
			
		||||
@@ -53,7 +53,22 @@ def submodule_func_from_type(bone_type):
 | 
			
		||||
    return submod, getattr(submod, func_name)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def submodule_types():
 | 
			
		||||
    import os
 | 
			
		||||
    submodules = []
 | 
			
		||||
    files = os.listdir(os.path.dirname(__file__))
 | 
			
		||||
    for f in files:
 | 
			
		||||
        if not f.startswith("_") and f.endswith(".py"):
 | 
			
		||||
            submodules.append(f[:-3])
 | 
			
		||||
    
 | 
			
		||||
    return sorted(submodules)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def validate_rig(context, obj):
 | 
			
		||||
    '''
 | 
			
		||||
    Makes no changes
 | 
			
		||||
    only runs the metarig definitions and reports errors
 | 
			
		||||
    '''
 | 
			
		||||
    type_found = False
 | 
			
		||||
    
 | 
			
		||||
    for pbone in obj.pose.bones:
 | 
			
		||||
@@ -81,6 +96,9 @@ def validate_rig(context, obj):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
 | 
			
		||||
    '''
 | 
			
		||||
    Main function for generating 
 | 
			
		||||
    '''
 | 
			
		||||
    from collections import OrderedDict
 | 
			
		||||
    import rigify_utils
 | 
			
		||||
    reload(rigify_utils)
 | 
			
		||||
@@ -307,20 +325,11 @@ def generate_test(context, metarig_type="", GENERATE_FINAL=True):
 | 
			
		||||
            obj.selected = False
 | 
			
		||||
        obj_new.selected = True
 | 
			
		||||
 | 
			
		||||
    files = os.listdir(os.path.dirname(__file__))
 | 
			
		||||
    for f in files:
 | 
			
		||||
        if f.startswith("_"):
 | 
			
		||||
            continue
 | 
			
		||||
 | 
			
		||||
        if not f.endswith(".py"):
 | 
			
		||||
            continue
 | 
			
		||||
 | 
			
		||||
        module_name = f[:-3]
 | 
			
		||||
        
 | 
			
		||||
    for module_name in submodule_types():
 | 
			
		||||
        if (metarig_type and module_name != metarig_type):
 | 
			
		||||
            continue
 | 
			
		||||
        
 | 
			
		||||
        submodule = __import__(name="%s.%s" % (__package__, module_name), fromlist=[module_name])
 | 
			
		||||
        submodule, func = submodule_func_from_type(module_name)
 | 
			
		||||
 | 
			
		||||
        metarig_template = getattr(submodule, "metarig_template", None)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -24,8 +24,21 @@ from rna_prop_ui import rna_idprop_ui_prop_get
 | 
			
		||||
 | 
			
		||||
METARIG_NAMES = ("cpy",)
 | 
			
		||||
 | 
			
		||||
# note, this example is just a bone with copy property.
 | 
			
		||||
def metarig_template():
 | 
			
		||||
    pass
 | 
			
		||||
    # generated by rigify.write_meta_rig
 | 
			
		||||
    bpy.ops.object.mode_set(mode='EDIT')
 | 
			
		||||
    obj = bpy.context.active_object
 | 
			
		||||
    arm = obj.data
 | 
			
		||||
    bone = arm.edit_bones.new('Bone')
 | 
			
		||||
    bone.head[:] = 0.0000, 0.0000, 0.0000
 | 
			
		||||
    bone.tail[:] = 0.0000, 0.0000, 1.0000
 | 
			
		||||
    bone.roll = 0.0000
 | 
			
		||||
    bone.connected = False
 | 
			
		||||
 | 
			
		||||
    bpy.ops.object.mode_set(mode='OBJECT')
 | 
			
		||||
    pbone = obj.pose.bones['Bone']
 | 
			
		||||
    pbone['type'] = 'copy'
 | 
			
		||||
 | 
			
		||||
def metarig_definition(obj, orig_bone_name):
 | 
			
		||||
    return [orig_bone_name]
 | 
			
		||||
 
 | 
			
		||||
@@ -162,6 +162,26 @@ def main(obj, bone_definition, base_names):
 | 
			
		||||
    # *****
 | 
			
		||||
    driver = driver_fcurves[2].driver
 | 
			
		||||
    driver.expression = "(1.0-cos(x))-s"
 | 
			
		||||
 | 
			
		||||
    def x_direction():
 | 
			
		||||
        # NOTE: the direction of the Z rotation depends on which side the palm is on.
 | 
			
		||||
        # we could do a simple side-of-x test but better to work out the direction
 | 
			
		||||
        # the hand is facing.
 | 
			
		||||
        from Mathutils import Vector, AngleBetweenVecs
 | 
			
		||||
        from math import degrees
 | 
			
		||||
        child_pbone_01 = obj.pose.bones[children[0]]
 | 
			
		||||
        child_pbone_02 = obj.pose.bones[children[1]]
 | 
			
		||||
 | 
			
		||||
        rel_vec = child_pbone_01.head - child_pbone_02.head
 | 
			
		||||
        x_vec = child_pbone_01.matrix.rotationPart() * Vector(1.0, 0.0, 0.0)
 | 
			
		||||
        return degrees(AngleBetweenVecs(rel_vec, x_vec)) > 90.0
 | 
			
		||||
 | 
			
		||||
    if x_direction(): # flip
 | 
			
		||||
        driver.expression = "-(%s)" % driver.expression
 | 
			
		||||
    
 | 
			
		||||
    for fcurve in driver_fcurves:
 | 
			
		||||
        fcurve.modifiers.remove(0) # grr dont need a modifier
 | 
			
		||||
 | 
			
		||||
    tar = driver.targets.new()
 | 
			
		||||
    tar.name = "x"
 | 
			
		||||
    tar.id_type = 'OBJECT'
 | 
			
		||||
 
 | 
			
		||||
@@ -182,6 +182,15 @@ class INFO_MT_mesh_add(dynamic_menu.DynMenu):
 | 
			
		||||
        layout.operator("mesh.primitive_grid_add", icon='MESH_GRID', text="Grid")
 | 
			
		||||
        layout.operator("mesh.primitive_monkey_add", icon='MESH_MONKEY', text="Monkey")
 | 
			
		||||
 | 
			
		||||
class INFO_MT_armature_add(dynamic_menu.DynMenu):
 | 
			
		||||
    bl_idname = "INFO_MT_armature_add"
 | 
			
		||||
    bl_label = "Armature"
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        layout.operator_context = 'INVOKE_REGION_WIN'
 | 
			
		||||
        layout.operator("object.armature_add", text="Single Bone", icon='BONE_DATA')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class INFO_MT_add(bpy.types.Menu):
 | 
			
		||||
    bl_label = "Add"
 | 
			
		||||
@@ -198,27 +207,20 @@ class INFO_MT_add(bpy.types.Menu):
 | 
			
		||||
        layout.operator_menu_enum("object.surface_add", "type", text="Surface", icon='OUTLINER_OB_SURFACE')
 | 
			
		||||
        layout.operator_menu_enum("object.metaball_add", "type", 'META', text="Metaball", icon='OUTLINER_OB_META')
 | 
			
		||||
        layout.operator("object.text_add", text="Text", icon='OUTLINER_OB_FONT')
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator_context = 'INVOKE_REGION_WIN'
 | 
			
		||||
 | 
			
		||||
        layout.operator("object.armature_add", text="Armature", icon='OUTLINER_OB_ARMATURE')
 | 
			
		||||
        layout.menu("INFO_MT_armature_add", icon='OUTLINER_OB_ARMATURE')
 | 
			
		||||
        layout.operator("object.add", text="Lattice", icon='OUTLINER_OB_LATTICE').type = 'LATTICE'
 | 
			
		||||
        layout.operator("object.add", text="Empty", icon='OUTLINER_OB_EMPTY').type = 'EMPTY'
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator("object.add", text="Camera", icon='OUTLINER_OB_CAMERA').type = 'CAMERA'
 | 
			
		||||
 | 
			
		||||
        layout.operator_context = 'EXEC_SCREEN'
 | 
			
		||||
 | 
			
		||||
        layout.operator_menu_enum("object.lamp_add", "type", 'LAMP', text="Lamp", icon='OUTLINER_OB_LAMP')
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator_menu_enum("object.effector_add", "type", 'EMPTY', text="Force Field", icon='OUTLINER_OB_EMPTY')
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator_menu_enum("object.group_instance_add", "type", text="Group Instance", icon='OUTLINER_OB_EMPTY')
 | 
			
		||||
@@ -292,6 +294,7 @@ bpy.types.register(INFO_MT_file_export)
 | 
			
		||||
bpy.types.register(INFO_MT_file_external_data)
 | 
			
		||||
bpy.types.register(INFO_MT_add)
 | 
			
		||||
bpy.types.register(INFO_MT_mesh_add)
 | 
			
		||||
bpy.types.register(INFO_MT_armature_add)
 | 
			
		||||
bpy.types.register(INFO_MT_game)
 | 
			
		||||
bpy.types.register(INFO_MT_render)
 | 
			
		||||
bpy.types.register(INFO_MT_help)
 | 
			
		||||
 
 | 
			
		||||
@@ -198,7 +198,7 @@ static void graph_panel_properties(const bContext *C, Panel *pa)
 | 
			
		||||
	/* RNA-Path Editing - only really should be enabled when things aren't working */
 | 
			
		||||
	col= uiLayoutColumn(layout, 1);
 | 
			
		||||
		uiLayoutSetEnabled(col, (fcu->flag & FCURVE_DISABLED)); 
 | 
			
		||||
		uiItemR(col, "", ICON_RNA, &fcu_ptr, "rna_path", 0);
 | 
			
		||||
		uiItemR(col, "", ICON_RNA, &fcu_ptr, "data_path", 0);
 | 
			
		||||
		uiItemR(col, NULL, 0, &fcu_ptr, "array_index", 0);
 | 
			
		||||
		
 | 
			
		||||
	/* color settings */
 | 
			
		||||
@@ -396,7 +396,7 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
 | 
			
		||||
			col= uiLayoutColumn(box, 1);
 | 
			
		||||
			block= uiLayoutGetBlock(col);
 | 
			
		||||
				/* rna path */
 | 
			
		||||
				uiTemplatePathBuilder(col, (bContext *)C, &dtar_ptr, "rna_path", &root_ptr, "Path");
 | 
			
		||||
				uiTemplatePathBuilder(col, (bContext *)C, &dtar_ptr, "data_path", &root_ptr, "Path");
 | 
			
		||||
				
 | 
			
		||||
				/* array index */
 | 
			
		||||
				// TODO: this needs selector which limits it to ok values
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user