Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #===============================================================================
- # Create Joints on Edges
- # author: Bradon Webb
- # 02/17/13
- #
- #
- # To use script select edges from a polygon mesh in order that you want the joint chain
- # run script and it will make joints where each edge was.
- #
- # You need to manually do a rigid bind the joints to the mesh
- #===============================================================================
- import maya.cmds as mc
- import maya.OpenMaya as om
- import pymel.core as pm
- import math
- def getDistance(vec1, vec2):
- '''
- @summary:
- test two points in space to determine which one is bigger
- @arguments:
- two point vectors
- @returns:
- the differnce between the two points
- '''
- dist = vec1 - vec2
- return dist
- #return math.sqrt(dist.x**2 + dist.y**2 + dist.z**2)
- def createHierarchy(nodeList=['object1,object2']):
- '''
- @summary:
- will create a hierarchy chain, simmilar to a joint hierarchy out of a list of objects
- @arguments:
- list of object names
- @returns:
- nothing
- '''
- #reverse the list
- nodeList.reverse()
- # get the length of the list
- selectionLength = len(nodeList)
- # Loop through the selection list
- for index, node in enumerate(nodeList):
- # Check to make sure its not the last element in the list
- if index < (selectionLength - 1):
- # parent the node to the previously selected node
- mc.parent(node, nodeList[index + 1])
- # Debuggin
- #print "node", node
- #print "child", nodeList[index + 1]
- #print "index", index
- def calculateEdgeCenter(edge='polyObject.e[0]'):
- '''
- @summary:
- gets the worldspace center given edge
- libraries pymel, openMaya
- @arguments:
- edge = name of the edge as a string
- @returns:
- worldspace XYZ coordinates of the center of that edge
- '''
- edge = pm.MeshEdge(edge)
- # get the centerpoint of the edge
- edgept = edge.__apimfn__().center(om.MSpace.kWorld)
- edgecenterPoint = pm.datatypes.Point(edgept)
- print 'EDGECENTER:', edgecenterPoint
- return edgecenterPoint
- def createLineVector(point1 = om.MVector(0,0,0), point2 = om.MVector(1,1,0), name='vector'):
- '''
- @summary:
- given two point MVectors create a line - good for visualizing normals and angles
- @arguments:
- Point1 = MVector
- point2 = MVector
- name = string, names the created line
- @returns:
- curve name
- '''
- newCurve = mc.curve(name=name, worldSpace=True, degree=1,
- point=[(point1.x, point1.y, point1.z),
- (point2.x, point2.y, point2.z)])
- return newCurve
- def calculateRotations(pointOrigin=[0,0,0], pointX=[1,0,0], pointUP=[0,1,0]):
- '''
- @summary:
- calculates Euler rotation values 3 point locations (mVectors)
- @arguments:
- pointOrigin = position of origin point (MVector)
- pointX = position of x point (mVector)
- pointUP = position of up point (mVector)
- @returns:
- Euler rotation to rotate the object back
- [x,y,z]
- '''
- #rotOrder = mc.getAttr('%s.rotateOrder'%node)
- # hard code rotation order to xyz
- rotOrder = 0
- # Get Point Positions
- originPosition = pointOrigin
- XDirection = pointX
- UPDirection = pointUP
- #worldOrigin = om.MVector(0,0,0)
- # Subtract Positions for Vector
- UpVector = originPosition - UPDirection
- XAxis = XDirection - originPosition
- ZAxis = UpVector^XAxis
- YAxis = ZAxis^XAxis
- # Debugging
- #print 'XAxis:', XAxis.x, XAxis.y, XAxis.z
- #print 'UpVector:', UpVector.x, UpVector.y, UpVector.z
- #print 'ZAxis:', ZAxis.x, ZAxis.y, ZAxis.z
- #print 'YAxis:', YAxis.x, YAxis.y, YAxis.z
- XAxisNormalize = XAxis.normal()
- YAxisNormalize = YAxis.normal()
- ZAxisNormalize = ZAxis.normal()
- # Create lines in space for each axis: visual aid
- #xNormalCurve = createLineVector(point1=worldOrigin, point2=XAxisNormalize, name='XAxisNormalize')
- #yNormalCurve = createLineVector(point1=worldOrigin, point2=YAxisNormalize, name='YAxisNormalize')
- #zNormalCurve = createLineVector(point1=worldOrigin, point2=ZAxisNormalize, name='ZAxisNormalize')
- # Create axis group and move to origin point: visual aid
- #waxisGroup = mc.group([xNormalCurve,yNormalCurve,zNormalCurve], name='{node}_axisGroup'.format(node=node))
- # Debugging
- #print 'XAxisNormalize:', XAxisNormalize.x, XAxisNormalize.y, XAxisNormalize.z
- #print 'YAxisNormalize:', YAxisNormalize.x, YAxisNormalize.y, YAxisNormalize.z
- #print 'ZAxisNormalize:', ZAxisNormalize.x, ZAxisNormalize.y, ZAxisNormalize.z
- # pack values into matrix
- matrix = om.MMatrix()
- om.MScriptUtil.setDoubleArray(matrix[0], 0, XAxisNormalize.x) # Sets the first row, first column
- om.MScriptUtil.setDoubleArray(matrix[0], 1, XAxisNormalize.y) # Sets the first row, second column
- om.MScriptUtil.setDoubleArray(matrix[0], 2, XAxisNormalize.z) # Sets the first row, third column
- om.MScriptUtil.setDoubleArray(matrix[1], 0, YAxisNormalize.x) # Sets the second row, first column
- om.MScriptUtil.setDoubleArray(matrix[1], 1, YAxisNormalize.y) # Sets the second row, second column
- om.MScriptUtil.setDoubleArray(matrix[1], 2, YAxisNormalize.z) # Sets the second row, third column
- om.MScriptUtil.setDoubleArray(matrix[2], 0, ZAxisNormalize.x) # Sets the third row, first column
- om.MScriptUtil.setDoubleArray(matrix[2], 1, ZAxisNormalize.y) # Sets the third row, second column
- om.MScriptUtil.setDoubleArray(matrix[2], 2, ZAxisNormalize.z) # Sets the third row, third column
- # converts inverse matrix to center rotate points to 0
- matrixInverse = matrix.inverse()
- # Convert to MTransformationMatrix to extract rotations
- mTransformMtx = om.MTransformationMatrix(matrix)
- mTransformMtxInverse = om.MTransformationMatrix(matrixInverse)
- # Get the euler rotations
- eulerRot = mTransformMtx.eulerRotation()
- eulerRotInverse = mTransformMtxInverse.eulerRotation()
- # sort to the proper rotate order
- eulerRot.reorderIt(rotOrder)
- eulerRotInverse.reorderIt(rotOrder)
- # convert radians to degrees
- rotAngle = [math.degrees(angle) for angle in (eulerRot.x, eulerRot.y, eulerRot.z)]
- rotAngleInverse = [math.degrees(angle) for angle in (eulerRotInverse.x, eulerRotInverse.y, eulerRotInverse.z)]
- print 'ANGLES: ', rotAngle
- #print 'ANGLES INVERSE:', rotAngleInverse
- #return rotAngleInverse, rotAngle
- return rotAngle
- def createJointControls():
- '''
- @summary:
- creates a joint at the center of every selected edge
- @arguments:
- needs a selection of edges
- @returns:
- JointChain
- '''
- # This code works to retain the selected orderd
- selectedEdgeList = mc.ls(orderedSelection=True, long=True)
- #print 'EDGELIST:', selectedEdgeList
- # clear the selection
- mc.select(clear=True)
- # create a list to store the joints
- jointList = []
- numberOfEdges = len(selectedEdgeList)
- # for each edge in the list create a joint
- for index, selectedEdge in enumerate(selectedEdgeList):
- # test to make sure you are not on the last edge
- if index < (numberOfEdges - 1):
- # calculate the center of the next edge in the list
- UPDirection = om.MVector(calculateEdgeCenter(selectedEdgeList[index+1]))
- else:
- print "YUP_ DEFAULT"
- UPDirection = om.MVector(0,0,0)
- # Main Function
- # get the centerPoint
- edgeCenter = calculateEdgeCenter(selectedEdge)
- # get the position of endpoints of the edge
- edgeEndPoints = mc.xform(selectedEdge, query=True, worldSpace=True, translation=True)
- point1 = om.MVector(edgeEndPoints[0],edgeEndPoints[1],edgeEndPoints[2])
- point2 = om.MVector(edgeEndPoints[3],edgeEndPoints[4],edgeEndPoints[5])
- # determine the point order if point 1 is bigger than point 2
- distance = getDistance(point1, point2)
- # determine the magnitude of the difference in points
- direction = distance[0] + distance[1] + distance[2]
- # try to determine if the point order for X axis needs to flip
- if direction < 0.0:
- # set the point positions to define the rotation vector
- print "negative Distance"
- #zRot = 0
- originPosition = point1
- XDirection = point2
- else:
- print "positive Distance"
- #zRot = 180
- originPosition = point2
- XDirection = point1
- #UPDirection = om.MVector(0,0,0)
- # Main Function
- # get the rotation of the edge based on three points
- rotationAngle = calculateRotations(pointOrigin=originPosition, pointX=XDirection, pointUP=UPDirection)
- # create Joint at the edge center and aligned to the edge
- joint = mc.joint(position=edgeCenter, orientation=rotationAngle)
- # clear selection so the joints do not attach to one another
- mc.select(clear=True)
- #append joint name to list
- jointList.append(joint)
- # attach all the joints in a chain
- createHierarchy(nodeList=jointList)
- #newBindSkin " -byClosestPoint -toSkeleton";
- createJointControls()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement