Showing posts with label props rigging. Show all posts
Showing posts with label props rigging. Show all posts

Tuesday, January 28, 2020

simple prop rig for blender 2.79

this is a simple prop rig i wrote for blender 2.79, modify use at your own risk

simple prop rig for blender 2.79 from Nathan Anozie on Vimeo.



Happy Rigging, Scripting and Animating!
Nate

#naPropRigAddOn.py
#modify use at your own risk
bl_info = {
    "name":"prop rigging tool",
    "description":"tool to build a simple prop rig in blender",
    "category": "Object",
    "author":"Nathaniel Anozie",
    "blender":(2,79,0)
}

import bpy


from bpy.types import(
    Operator,
    Panel
    )

class propRigOperator(Operator):
    """first select single mesh for prop in object mode.
    """
    bl_idname = "obj.buildproprig" #needs to be all lowercase
    bl_label = "build propRig"
    bl_options = {"REGISTER"}

    def execute(self, context):
        naBuildRig(context)
        return {'FINISHED'}

class propRigPanel(Panel):
    bl_label = "propRig Panel"
    bl_space_type = "PROPERTIES"
    bl_region_type = "WINDOW"
    
    def draw(self, context):
        layout = self.layout
        layout.label(text = "first select single mesh geo of prop")
        layout.operator( "obj.buildproprig")

def register():
    bpy.utils.register_class(propRigOperator)
    bpy.utils.register_class(propRigPanel)
    
def unregister():
    bpy.utils.unregister_class(propRigOperator)
    bpy.utils.unregister_class(propRigPanel)
if __name__ == "__main__":
    register()




##actual procs going here
#for widgets
squareShapeVertsEdges = ([(-1.0, -1.0, 0.0), (1.0, -1.0, 0.0), (-1.0, 1.0, 0.0), (1.0, 1.0, 0.0)], [(2, 0), (0, 1), (1, 3), (3, 2)])
cubeShapeVertsEdges = ([(-1.0, -1.0, -1.0), (-1.0, -1.0, 1.0), (-1.0, 1.0, -1.0), (-1.0, 1.0, 1.0), (1.0, -1.0, -1.0), (1.0, -1.0, 1.0), (1.0, 1.0, -1.0), (1.0, 1.0, 1.0)], [(2, 0), (0, 1), (1, 3), (3, 2), (6, 2), (3, 7), (7, 6), (4, 6), (7, 5), (5, 4), (0, 4), (5, 1)])
circleShapeVertsEdges = ([(0.0, 1.0, 0.0), (-0.1951, 0.9808, 0.0), (-0.3827, 0.9239, 0.0), (-0.5556, 0.8315, 0.0), (-0.7071, 0.7071, 0.0), (-0.8315, 0.5556, 0.0), (-0.9239, 0.3827, 0.0), (-0.9808, 0.1951, 0.0), (-1.0, 0.0, 0.0), (-0.9808, -0.1951, 0.0), (-0.9239, -0.3827, 0.0), (-0.8315, -0.5556, 0.0), (-0.7071, -0.7071, 0.0), (-0.5556, -0.8315, 0.0), (-0.3827, -0.9239, 0.0), (-0.1951, -0.9808, 0.0), (0.0, -1.0, 0.0), (0.1951, -0.9808, 0.0), (0.3827, -0.9239, 0.0), (0.5556, -0.8315, 0.0), (0.7071, -0.7071, 0.0), (0.8315, -0.5556, 0.0), (0.9239, -0.3827, 0.0), (0.9808, -0.1951, 0.0), (1.0, 0.0, 0.0), (0.9808, 0.1951, 0.0), (0.9239, 0.3827, 0.0), (0.8315, 0.5556, 0.0), (0.7071, 0.7071, 0.0), (0.5556, 0.8315, 0.0), (0.3827, 0.9239, 0.0), (0.1951, 0.9808, 0.0)], [(1, 0), (2, 1), (3, 2), (4, 3), (5, 4), (6, 5), (7, 6), (8, 7), (9, 8), (10, 9), (11, 10), (12, 11), (13, 12), (14, 13), (15, 14), (16, 15), (17, 16), (18, 17), (19, 18), (20, 19), (21, 20), (22, 21), (23, 22), (24, 23), (25, 24), (26, 25), (27, 26), (28, 27), (29, 28), (30, 29), (31, 30), (0, 31)])


def naBuildRig(context):
    """build simple prop rig with 3 animator controls.
    requires single mesh selected in object mode
    """
    #if armature doesnt exist make it
    print('makeArmature')
    
    sel = context.selected_objects #context.object doesnt work for addon
    if not sel:
        print("requires a mesh selected in object mode to prop")
        return
    propObj = sel[0]
    if (propObj is None) or (propObj.type != "MESH"):
        print("requires a mesh selected in object mode to prop")
        return
        
    propName = propObj.name#"Cube" #Change all the hard coded names later
    name = "%s_armature" %(propName)
    
    ###Making armature
    if name in bpy.data.objects:
        print('armature already created %s skipping' %(name))
        return bpy.data.objects[name]
    
    arm_dat = None
    if name in bpy.data.armatures:
        print('armatures with name already created %s removing it' %(name))
        armature = bpy.data.armatures[name]
        bpy.data.armatures.remove(armature)
    
    arm_dat = bpy.data.armatures.new(name)
        
    arm_obj = bpy.data.objects.new(name,arm_dat)
    arm_obj.data = arm_dat
    
    scene = context.scene
    scene.objects.link(arm_obj)
    scene.objects.active = arm_obj #need to select armature to put it in edit mode
    scene.update()
    ####
    
    
    ###Make bones in armature
    bpy.ops.object.mode_set(mode='EDIT', toggle=False)
    
    rootBoneName = "%s_root_anim" %(propName)
    rootBone = bpy.data.armatures[name].edit_bones.new(rootBoneName)
    rootBone.head = (0,0,0)
    rootBone.tail = (0,1,0)

    midPosZ = propObj.dimensions.z/2 #midPosZ = 5 #get from dimensions of prop geo
    midABoneName = "%s_mida_anim" %(propName)
    midABone = bpy.data.armatures[name].edit_bones.new(midABoneName)
    midABone.head = (0,0,midPosZ)
    midABone.tail = (0,1,midPosZ)

    midBBoneName = "%s_midb_anim" %(propName)
    midBBone = bpy.data.armatures[name].edit_bones.new(midBBoneName)
    midBBone.head = (0,0,midPosZ)
    midBBone.tail = (0,1,midPosZ)
    
    ##handle parenting of bones
    print("doing parenting")
    context.scene.objects.active = arm_obj
    bpy.ops.object.mode_set(mode='EDIT', toggle=False)
    if arm_obj == context.active_object and context.mode == "EDIT_ARMATURE":
        print("parenting bone >>")
        arm_obj.data.edit_bones[midBBoneName].parent = arm_obj.data.edit_bones[midABoneName]
        arm_obj.data.edit_bones[midABoneName].parent = arm_obj.data.edit_bones[rootBoneName]
    print("finished parenting bone")

    bpy.ops.object.mode_set(mode='OBJECT')
    
    ##make widgets for bones
    rootWidgetName = "%s_root_wdgt" %("naProp") #so all prop rigs use same widgets
    midAWidgetName = "%s_mida_wdgt" %("naProp")
    midBWidgetName = "%s_midb_wdgt" %("naProp")
    if not rootWidgetName in bpy.data.objects:
        rootWidgetShape = drawShape( context, name=rootWidgetName, shapeVertsEdges=cubeShapeVertsEdges)
    else:
        rootWidgetShape = bpy.data.objects[rootWidgetName]
    #z scaling of root widget
    rootWidgetShape.scale.z = 0.1
    rootWidgetShape.select = True
    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
    
    if not midAWidgetName in bpy.data.objects:
        midAWidgetShape = drawShape( context, name=midAWidgetName, shapeVertsEdges=squareShapeVertsEdges)
    else:
        midAWidgetShape = bpy.data.objects[midAWidgetName]
        
    if not midBWidgetName in bpy.data.objects:
        midBWidgetShape = drawShape( context, name=midBWidgetName, shapeVertsEdges=circleShapeVertsEdges)
    else:
        midBWidgetShape = bpy.data.objects[midBWidgetName]
        
    #put widgets in last layer so they are not seen
    rootWidgetShape.layers = [False]*19+[True]
    midAWidgetShape.layers = [False]*19+[True]
    midBWidgetShape.layers = [False]*19+[True]
    
    ##add widgets to bones
    bpy.ops.object.mode_set(mode='OBJECT')
    arm_obj.pose.bones[rootBoneName].custom_shape = rootWidgetShape
    arm_obj.data.bones[rootBoneName].show_wire=True

    arm_obj.pose.bones[midABoneName].custom_shape = midAWidgetShape
    arm_obj.data.bones[midABoneName].show_wire=True
    
    arm_obj.pose.bones[midBBoneName].custom_shape = midBWidgetShape
    arm_obj.data.bones[midBBoneName].show_wire=True
    
    ##set rotation mode to bones
    arm_obj.pose.bones[rootBoneName].rotation_mode = 'XYZ'
    arm_obj.pose.bones[midABoneName].rotation_mode = 'XYZ'
    arm_obj.pose.bones[midBBoneName].rotation_mode = 'XYZ'

    
    ##resize widgets using prop geo
    propScale = 1.5*propObj.dimensions.x/2
    for boneName in [rootBoneName,midABoneName,midBBoneName]:
        arm_obj.pose.bones[boneName].custom_shape_scale = propScale
    
    #make prop geo follow armature
    #using constraint (possibly later change to parenting)
    cnt = propObj.constraints.new('CHILD_OF')
    cnt.target = arm_obj
    cnt.subtarget = midBBoneName
    poseDrivingBone = arm_obj.pose.bones[midBBoneName]
    ##prevent offset because driving bone not at origin
    cnt.inverse_matrix = (arm_obj.matrix_world*poseDrivingBone.matrix).inverted()
    #end make prop geo follow armature
    
    return arm_obj



###helper for widgets for bones
def drawShape(context, name = None, shapeVertsEdges = None):
    """ draw mesh no faces. if it exists does nothing. it takes name of shape and tuple with lists for verts and edges"""
    if not name:
        print("requires a name >> exiting")
        return
        
    scene = context.scene
    
    #if data object already created return the object 
    if name in bpy.data.objects:
        print("%s is already created doing nothing" %name)
        return bpy.data.objects[name]

    
    #create the object in data
    mesh = bpy.data.meshes.new(name)
    obj = bpy.data.objects.new(name,mesh)
    scene.objects.link(obj)
    
    if obj is None:
        print("issue drawing shape")
        return None
        
    #use for from_pydata
    verts,edges = shapeVertsEdges
    meshData = obj.data
    meshData.from_pydata(verts,edges,[])
    meshData.update()
    
    return obj

def getVertsEdgesFromSelected(context):
    """help for from_pydata creation of widgets. returns tuple verts and edges of selected
    """
    obj = context.selected_objects[0]
    
    verts = []
    edges = []
    
    for i in range(0,len(obj.data.vertices)):
        pos = context.object.data.vertices[i].co
        verts.append( tuple( (round(pos[0],4),round(pos[1],4),round(pos[2],4)) )  )
    for i in range(0,len(obj.data.edges)):
        edges.append( (context.object.data.edges[i].vertices[0],context.object.data.edges[i].vertices[1])  )
        
    return verts,edges
    
##inspired by
#Nathan Vegdahl's rigify
#https://blenderartists.org/t/how-to-update-bpy-data-meshes-bpy-data-armatures/592370
#https://blender.stackexchange.com/questions/18562/child-ofs-set-inverse-without-using-bpy-ops
#https://blender.stackexchange.com/questions/112776/parent-object-to-a-bone-and-object-becomes-offsets-how-do-i-prevent-object-from  ##parenting mesh to bone

Saturday, December 28, 2019

some tips for making a simple cabinet rig in blender

Hi,
here are some tips for making a simple cabinet prop rig in blender.  hope you find them helpful.

making of armature
4 bones to open cabinets - 2 on each side
2 bones mid
1 bone origin

added an armature and made 2 center bones and root bone:

made one of the mid bones shorter so can select it easier changing tail to 0.7


figuring out origin point for cabinet bone. using cursor to selected on cabinet verts:


orient cabinet bone so rotating in +z opens cabinet by adjusting roll:


create other cabinet bone from first.(used the cursor to selected trick then the >> selection to cursor to position second bone)

set bones rotations to xyz euler (i think this should work for this simple example). lock scales for all bones except root bone.

setup the parenting
-select child then parent >> ctrl+p keep offset

mirror left bones to right side.
-in edit mode select left side bones >> armature >> symmetrize .L bones get renamed to .R on right side

- need to fix roll on right side bones so +z opens cabinet doors.  used roll 180 on right side bones.

parent meshes to relevant bone
-in pose mode >> select child then parent >> ctrl+p bone option

add widgets for bones (make sure display wireframe is checked so can see controls in solid shaded view)


modelling tips
(separate face to make handles ‘p’ in edit mode ‘selection’)
(join meshes ctrl+j to make cabinet body and also to add handles to cabinets)
(apply transforms to reset locations,scales,rotates)
(to mirror half cabinet to other side shift+d to duplicate >> then object mirror x global >> enter to complete)

script ideas from this:
-be nice to have a script that mirrors meshes in x axis and edits names so meshes with .L become .R
-might want a script to rename meshes.name from object.name

inspired by:
https://blender.stackexchange.com/questions/76584/how-to-align-or-mirror-half-armature

Happy Rigging!
Nate

Monday, December 23, 2019

pencil rig v1

Hi,
This is a simple pencil rig i made in blender.

pencil rig v1 from Nathan Anozie on Vimeo.

These are some steps i took in making this:

making armature
2 bones midway
1 bone at origin

add origin bone so its translate channels match with world axis.
ex when its translated in pose mode:


duplicate origin bone twice to make mid bones.
make it easier to see mid bones ontop of each other (envelope view adjusting envelope/head/tail radius). view wireframe mode


parented one mid bone _b to second mid bone _a.  parent mid bone _a to root.(select child then parent >> ctrl+p keep offset)
so move root moves all bones.

parent pencil mesh geo to innermost mid bone.  select mesh then mid bone b then ctrl+p parent bone option.

-add widgets for bones
circle >> square >> triangle (from square merging 2 verts with alt+m >> center) (for making widgets switch to solid view to see faces)
assign widgets to appropriate bones>> check on display wireframe for bones. then put widgets in last layer >> select them >> m >> pick last layer

-clean up
make mesh unselectable (arrow icon in outliner)
switch to solid view
could hide relationship lines when done (in n panel >> display)


(on the side for making pencil >> started with cylinder >> adjusted dimension/scale to get rough proportions >> selected cap edge loop extruded with E (to select edge loop alt+rightclick on edge in edge mode) >> merged extruded vertices to center alt+m)

Happy Rigging!
Nate

Saturday, December 21, 2019

picture frame rig v1

Hi,
this is a simple picture frame rig. it still needs a couple more controls and possibly movable pivot.

picture frame rig v1 from Nathan Anozie on Vimeo.
these are some of the steps i used to create this.

making picture frame armature
-orient armature root bone to match world. use armature axes on to see. ex: rx -90

-using geo vertices to position stand bone.  ‘cursor to selected’ and ‘selected to cursor’. to get bone following stand


use roll to get proper direction for in pose mode rotations here +x should move stand closer to frame. (ex: roll 180)

using envelope view so can see different bones on top of one another. changing radius of head/tail and envelope.(alt+s)
parent frame and stand bones to root.  (in edit mode select child then parent then ctrl+p)

parent frame and stand geo to bones. (in pose mode select child then parent then ctrl+p bone option)

making custom shapes for stand/frame/root.
could make shapes using add mesh.  then square ones from a plane after deleting face. made a different shape for each animated bone. (put created widgets in last layer >> select mesh >> m shortcut >> pick layer)
(so just shapes and no envelope displayed switched armature display back to octahedral/axes off)



did some cleanup like lock channels that weren't being used. here left scales and all rotations open on root animatable bone.

—tool ideas from making this
-make meshes unselectable (arrow icon in outliner)
bpy.context.object.hide_select = True
-way to draw a bone to match orientation of 4 vertex plane
-way to lock rotations/locations channels
-way to import geometry from one blend file to another

Happy Rigging!
Nate