I recently found out that highend3d, which used to be Creative Crash, might be going away.
So I’ve created a Gumroad account: https://alrichardson.gumroad.com/
and started moving my tools there, more to come!
I recently found out that highend3d, which used to be Creative Crash, might be going away.
So I’ve created a Gumroad account: https://alrichardson.gumroad.com/
and started moving my tools there, more to come!
My most recent demo reel is of my work at PlaySide Studios where I have been rigging characters and looking after artist tools and pipeline.
In this demo reel I am showing the final rendered mesh of the asset, the skeleton of the asset, to demonstrate the capabilities of the rig and its efficiencies. Then showing a wireframe overlay to display the deformation of the character clearly.
I did some digging around in my Vimeo page today and I’ve found some old gems!
Here is a Auto rigger demo from a T-Rex rig I built back in 2013.
Nice little tool which looks for you ‘scenes’ folder and sets the project to that location:
import maya.cmds as cmds import maya.mel as mel import maya.OpenMaya as om def setProj(): # find directory currentDir = cmds.file( query = True, location = True ) # dicect directory and set project try: projectDir,garbage = currentDir.split( 'scenes' ) except: return om.MGlobal.displayError( 'You need to have you file in a project folder structurte first' ) mel.eval( 'setProject ' + '"' + projectDir + '"' ) om.MGlobal.displayInfo( 'current project set to : ' + projectDir ) del projectDir del garbage setProj()
I’ve uploded my first tool to creativecrash!
http://www.creativecrash.com/maya/script/arjointorient
Its a tool I’ve written for orienting joints in Maya.
I wrote the tool for my own use, then after a while,
a few iterations and some UI building I decided to post
it so other people could give it a shot.
If you’re reading this, give it a go yourself!
Today I wrote a little tool that simply groups whatever you have selected, for the purposes of cleaning up transforms. Also works with multiple objects selected and groups them all under a group in the same worldspace as the first selected object.
Grab the code here and place it on your shelf.
import maya.cmds as cmds import maya.OpenMaya as om grpList = cmds.ls(sl = True) parentObj = cmds.listRelatives( grpList[0], parent = True ) cmds.group( em = True, name = grpList[0] + '_Zero_GRP' ) cmds.parentConstraint( grpList[0], grpList[0] + '_Zero_GRP' ) cmds.delete( grpList[0] + '_Zero_GRP_parentConstraint1' ) cmds.scaleConstraint( grpList[0], grpList[0] + '_Zero_GRP' ) cmds.delete( grpList[0] + '_Zero_GRP_scaleConstraint1' ) cmds.parent( grpList[0], grpList[0] + '_Zero_GRP' ) try: cmds.parent( grpList[0] + '_Zero_GRP', parentObj ) om.MGlobal.displayInfo( grpList[0] + ' now has a group above it' ) except: om.MGlobal.displayInfo( grpList[0] + ' has no parent object, grouped in world space' ) cmds.select( grpList[0] ) newParent = cmds.listRelatives( parent = True ) listEndNumber = len(grpList) remainingObj = grpList[1:int(listEndNumber)] for i in remainingObj: cmds.parent( i, newParent ) om.MGlobal.displayInfo( grpList[0] + ' now has a group above it' )
I keep coming back to procedural generation. Something about the unpredictable nature of parametric design really piques my interest.
I’ve begun scripting a system that will be the basis of a generative project, here it is:
import maya.cmds as cmds import random curveNumber = 1 curveName = 'string' + str(random.randrange(1,100)) count = 0 for i in range(0,curveNumber): pointNumber = random.randrange(4,100) pointArray = [(0,0,0)] * pointNumber cmds.curve( name = curveName + str(count).zfill(3), degree = 3, point = pointArray ) pointCount = 0 directionX = (random.random() -0.5 ) directionY = (random.random() -0.0 ) directionZ = (random.random() -0.5 ) curveAmount = 0.00001 * random.randrange(1,100) for i in range(0,int(pointNumber)): oldCurveAmount = curveAmount cmds.setAttr( curveName + str(count).zfill(3) + '.controlPoints' + str([pointCount]), pointCount * directionX * curveAmount, pointCount * directionY, pointCount * directionZ * curveAmount ) curveAmount = curveAmount * 1.1 print curveAmount print oldCurveAmount pointCount += 1 count +=1
This script creates curves of different lengths and CV counts, then arcs them in different directions. I’m hoping to have them arc back as the angle becomes steeper to create an organic curving line.
During the last job I was on, we were receiving rigs from another company.
These rigs did not always match our hierarchy and naming conventions, so, part of my job was to recompile these rigs to match our conventions. One common and potentially time consuming job was the renaming of control curves.
We would receive them with naming conventions along the lines of ‘*_Ctrl_01’, ‘*_Ctrl_02’ and so on.
Renaming every control in the rig is neigh on impossible, so I wrote a script to do so!
The script I wrote was smashed together with no time for optimization but now with a little time on my hands I have rewritten it to be user friendly and fast.
Here it is, have a look!
import maya.cmds as cmds selection = cmds.ls( sl = True) for i in selection: shape = cmds.listRelatives( i, shapes = True ) if shape == None: print 'No shape for ' + i + ', aborting.' else: try: a,b = i.split('_Ctrl') cmds.rename( i, a + b + '_Ctrl' ) except: print 'No Ctrl in name of ' + i
I spent today putting finishing touches on a script that saves a new version of the current scene. and a button icon to go with!
Grab the script here and pop it on your shelf.
################################################################################################ ################################################################################################ ### Save new version of current scene ### ### By Alastair Richardson ### ### May, 2013 ### ### Intended for Maya Ascii files ### ### Use: ### ### padding is the number of digits in the version number. ### ### ### ### versionIndicator is the characters that come before ### ### the version number. May be _V or _v depending on your ### ### pipeline. ### ### ### ### fileCountNumbering can be set to True or False. ### ### If set to True, the next version number will be obtained ### ### by counting the number of files in the working folder. ### ### This method is unpredictable if folder contains additional ### ### files or folders. ### ### ### ### If set to False, the next version number will be obtained ### ### using the current version number, can be risky if rolling ### ### to old versions is required. ### ### ### ################################################################################################ ################################################################################################ padding = 3 versionIndicator = '_v' fileCountNumbering = True ################################################################################################ ### ### ### Change script at your own risk ### ### ### ################################################################################################ import maya.cmds as cmds from pymel.core import * import maya.OpenMaya as om import os def saveNewVer(): # find directory currentDir = cmds.file( query = True, location = True ) splitDir = currentDir.split('/') length = len(splitDir) lessOne = length - 1 shortDir = splitDir[0:lessOne] directoryToOpen = '/'.join(shortDir) # create next version number of file if fileCountNumbering == True : # find the next version based on number of files on directory currentFileName = splitDir[length -1] versionSpilt = currentFileName.split(versionIndicator) currentName = versionSpilt[0] files = os.listdir( directoryToOpen ) mayaAscii = [] for i in files: try: a,b = i.split('.') except: print i + ' has no extension' if b == 'ma': mayaAscii.append(i) else: print str(i) + ' is not a Maya ASCII' nextVersion = len(mayaAscii) + 1 else: # find version by disecting current file name at _v currentFileName = splitDir[length -1] versionSpilt = currentFileName.split(versionIndicator) sansMA = versionSpilt[1].split('.') currentVersion = sansMA[0] currentName = versionSpilt[0] nextVersion = int(currentVersion) + 1 # do the saving newDirName = directoryToOpen + '/' + currentName + versionIndicator + str(nextVersion).zfill(padding) Mel.eval( "source addRecentFile.mel" ) Mel.eval('addRecentFile "%s" "%s";' % (newDirName + '.ma', 'mayaAscii')) cmds.file( rename = newDirName ) cmds.file( save = True ) om.MGlobal.displayInfo( 'saved to ' + newDirName ) saveNewVer()