Updates coming soon!
Proxy Pose
Motion Blur
3D sculpt inspired by mixed martial arts.
A video series explaining the concept and scripting a tool to setup and interact with space switching setup for rigs.
Small project with simulated rigid bodies and nParticle effects.
A tutorial on using the spline deformer on custom geometry to create muscle flexing and stretching behavior.
import maya.cmds as cmds from functools import partial def rotateContext(axis, *args): cmds.manipRotateContext( 'Rotate', e=True, ah=axis) if cmds.window("rotateContextUI", exists=True): cmds.deleteUI("rotateContextUI") win = cmds.window("rotateContextUI", title="Rotate Axis UI", w=150, sizeable=False) cmds.rowColumnLayout(nc=3, columnAttach=[(1,"both", 2), (3, "both", 2)]) cmds.button("X", w=30, bgc=[1,0,0], c=partial(rotateContext, 0)) cmds.button("Y", w=30, bgc=[0,1,0], c=partial(rotateContext, 1)) cmds.button("Z", w=30, bgc=[0,0,1], c=partial(rotateContext, 2)) cmds.showWindow(win)
import lpDynamicChains reload(lpDynamicChains) lpDynamicChains.UI()
from lpDynamicChains import * dynChain = lpDynamiChain(startJoint, endJoint) dynChain.create() def lpDyanmicChain(startJoint="", endJoint="", node=""): ''' Create the custom node Parameters: startJoint - Name of the first joint in the chain endJoint - Name of the last joint in the chain node - Name of the node to manage by the class Returns: Nothing ''' def create(self): ''' Create the actual dynamic joint chain node network Parameters: Nothing Returns: List of all new created nodes '''A custom locator node will be created at the start joint's position holding the parameters to be tweaked to customize the dynamic behavior of the joint chain.
from lpDynamicChains import * dynChain = lpDynamicChain(node=node) dynChain.delete() del(dynChain)Note: Removing dynamic nodes will also check for any unused nucleus nodes and remove them as well.
# create instance dynChain = lpDynamicChain() # create iterable for all dynamic nodes in the scene dynChains = dynChain.Iter() for d in dynChains: print dAdding Collision Objects
from lpDynamicChains import * nucleus = getActiveNucleus() setActiveNucleus(nucleus) def getActiveNucleus(): ''' Query the active nucleus node Parameters: Nothing Returns: Name of active nucleus node ''' def setActiveNucleus(nucleus): ''' Set the active nucleus node Parameters: nucleus - Name of nucleus node to set as current active nucleus Returns: Nothing '''Get Connected
from lpDynamicChains import * # get selected object obj = cmds.ls(sl=True)[0] dNode = getConnectedDynamicChain(obj) nucleus = getConnectedNucleusNode(dNode) def getConnectedDynamicChain(node): ''' Look for a valid DynamicChain node connected to the given node Parameters: node - Name of the node to find connection to DynamicChain Returns: Name of DynamicChain node connected to given node ''' def getConnectedNucleusNode(node): ''' Look for the nucleus node connected to the given node Parameters: node - Name of the node to find connection to nucleus Returns: Name of the nucleus node connected to the given node '''Checks
from lpDynamicChains import * # get selected object obj = cmds.ls(sl=True)[0] if isDynamicChain(obj): dynChain = lpDynamicChain(obj) # access attribute hairShape = dynChain.hairSystemShape[0] return isNType(hairShape, "hairSystem") def isDynamicChain(node): ''' Look for the identifier to check if node is 'dynamic' Parameters: node - Name of node to check for 'nodeType' Returns: Boolean value if node is dynamic or not, True or False ''' def isNType(node, nodeType): ''' Check if the given node is a nucleus compatible nDynamics node Parameters: node - Name of node to check for 'NType' compatibility nodeType - Node type to check Returns: Boolean value if node is compatible with nDynamics solver '''Number of Colliders
from lpDynamicChains import * # get selected object obj = cmds.ls(sl=True)[0] if isDynamicChain(obj): numColliders = findNumberOfCollisionObjects(obj) def findNumberOfCollisionObjects(node): ''' Find the number of collision objects attached to the node Parameters: node - Name of the node to check for collision objects Returns: Integer number of collision objects attached to the node '''Delete Unused Nucleus Nodes
from lpDynamicChains import * deletedNodes = deleteUnusedNucleusSolvers() def deleteUnusedNucleusSolvers(): ''' Delete all nucleus nodes not being used Parameters: Nothing Returns: List of nucleus node deleted '''Create and Connect
from lpDynamicChains import * # get selected objects selected = cmds.ls(sl=True)[0] dNode = selected[0] mesh = selected[1] nucleus = createNucleus() if isDynamicChain(dNode): nucleus = connectToNucleus(dNode, nucleus) nRigid = createNRigid(mesh, nucleus) index = connectNRigidToNucleus(nRigid, nucleus) def createNucleus(name="", setActive=True): ''' Create nucleus node Parameters: name - Name for the new nucleus node setActive - Boolean to set the new nucleus as the current active nucleus Returns: Name of new nucleus node ''' def createNRigid(obj, nucleus=""): ''' Create a nRigig node from the given obj Parameters: obj - Name of the geo to create nRigid from nucleus - Name of the nucleus to connect nRigid to Returns: Name of new nRigid node ''' def connectToNucleus(node, nucleus): ''' Connect the given node to the nucleus node Parameters: node - Name of the node to connect to the nucleus solver nucleus - Name of nucleus solver to connect to Returns: Name of nucleus node (debug) ''' def connectNRigidToNucleus(nRigid, nucleus, newNucleus=True): ''' Connect the given nRigid node to the nucleus node, maintaining prior connections to other nucleus nodes Parameters: nRigid - Name of nRigid node to connect to nucleus nucleus - Name of nucleus node to connect newNucleus - Boolean to create a new nucleus node if the specified nucleus doesn't exist Returns: Integer index of next available passive nRigid for the given nucleus '''Access connections
from lpDynamicChains import * # get selected object obj = cmds.ls(sl=True) if isDynamicChain(obj): dNode = lpDynamicChain(node=obj) nodes = dNode.listConnections() # get hairSystemShape node hairShape = dNode.hairSystemShape[0] def listConnections(self): ''' Wrapper to get all connections to the node to message attributes Parameters: Nothing Returns: List of connected nodes to all custom message attributes '''