Advertisement
bradon

EdgeToJoint V5

Feb 17th, 2013
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.83 KB | None | 0 0
  1.  
  2. #===============================================================================
  3. # Create Joints on Edges
  4. # author: Bradon Webb
  5. # 02/17/13
  6. #
  7. #
  8. # To use script select edges from a polygon mesh in order that you want the joint chain
  9. # run script and it will make joints where each edge was.
  10. #
  11. # You need to manually do a rigid bind the joints to the mesh
  12. #===============================================================================
  13.  
  14. import maya.cmds as mc
  15. import maya.OpenMaya as om
  16. import pymel.core as pm
  17. import math
  18.  
  19.  
  20. def getDistance(vec1, vec2):
  21.     '''
  22.    @summary:
  23.        test two points in space to determine which one is bigger
  24.    @arguments:
  25.            two point vectors
  26.    @returns:
  27.            the differnce between the two points
  28.    '''
  29.    
  30.     dist = vec1 - vec2
  31.     return dist
  32.     #return math.sqrt(dist.x**2 + dist.y**2 + dist.z**2)
  33.  
  34.  
  35. def createHierarchy(nodeList=['object1,object2']):
  36.     '''
  37.    @summary:
  38.        will create a hierarchy chain, simmilar to a joint hierarchy out of a list of objects
  39.    @arguments:
  40.        list of object names
  41.    @returns:
  42.        nothing
  43.    '''
  44.     #reverse the list
  45.     nodeList.reverse()
  46.    
  47.     # get the length of the list
  48.     selectionLength = len(nodeList)
  49.    
  50.     # Loop through the selection list
  51.     for index, node in enumerate(nodeList):
  52.         # Check to make sure its not the last element in the list
  53.         if index < (selectionLength - 1):
  54.             # parent the node to the previously selected node
  55.             mc.parent(node, nodeList[index + 1])            
  56.             # Debuggin
  57.             #print "node", node
  58.             #print "child", nodeList[index + 1]
  59.             #print "index", index
  60.  
  61.  
  62. def calculateEdgeCenter(edge='polyObject.e[0]'):
  63.     '''
  64.    @summary:
  65.        gets the worldspace center given edge
  66.        libraries pymel, openMaya
  67.    @arguments:
  68.        edge = name of the edge as a string
  69.    @returns:
  70.        worldspace XYZ coordinates of the center of that edge
  71.   '''
  72.     edge = pm.MeshEdge(edge)
  73.    
  74.     # get the centerpoint of the edge
  75.     edgept = edge.__apimfn__().center(om.MSpace.kWorld)
  76.     edgecenterPoint = pm.datatypes.Point(edgept)
  77.    
  78.     print 'EDGECENTER:', edgecenterPoint
  79.     return edgecenterPoint
  80.  
  81. def createLineVector(point1 = om.MVector(0,0,0), point2 = om.MVector(1,1,0), name='vector'):
  82.     '''
  83.    @summary:
  84.        given two point MVectors create a line - good for visualizing normals and angles
  85.    @arguments:
  86.        Point1 = MVector
  87.        point2 = MVector
  88.        name = string, names the created line
  89.    @returns:
  90.        curve name
  91.    '''
  92.  
  93.     newCurve = mc.curve(name=name, worldSpace=True, degree=1,
  94.                         point=[(point1.x, point1.y, point1.z),
  95.                                (point2.x, point2.y, point2.z)])
  96.     return newCurve
  97.  
  98. def calculateRotations(pointOrigin=[0,0,0], pointX=[1,0,0], pointUP=[0,1,0]):
  99.     '''
  100.    @summary:
  101.        calculates Euler rotation values 3 point locations (mVectors)
  102.    @arguments:
  103.        pointOrigin = position of origin point (MVector)
  104.        pointX = position of x point (mVector)
  105.        pointUP = position of up point (mVector)
  106.    @returns:
  107.        Euler rotation to rotate the object back
  108.        [x,y,z]
  109.    '''
  110.     #rotOrder = mc.getAttr('%s.rotateOrder'%node)
  111.     # hard code rotation order to xyz
  112.     rotOrder = 0
  113.    
  114.     # Get Point Positions
  115.     originPosition = pointOrigin
  116.     XDirection = pointX
  117.     UPDirection = pointUP
  118.     #worldOrigin = om.MVector(0,0,0)
  119.    
  120.     # Subtract Positions for Vector
  121.     UpVector = originPosition - UPDirection
  122.          
  123.     XAxis = XDirection - originPosition
  124.     ZAxis = UpVector^XAxis
  125.     YAxis = ZAxis^XAxis
  126.    
  127.     # Debugging
  128.     #print 'XAxis:', XAxis.x, XAxis.y, XAxis.z
  129.     #print 'UpVector:', UpVector.x, UpVector.y, UpVector.z
  130.     #print 'ZAxis:', ZAxis.x, ZAxis.y, ZAxis.z
  131.     #print 'YAxis:', YAxis.x, YAxis.y, YAxis.z
  132.        
  133.     XAxisNormalize = XAxis.normal()
  134.     YAxisNormalize = YAxis.normal()
  135.     ZAxisNormalize = ZAxis.normal()
  136.        
  137.     # Create lines in space for each axis: visual aid
  138.     #xNormalCurve = createLineVector(point1=worldOrigin, point2=XAxisNormalize,  name='XAxisNormalize')
  139.     #yNormalCurve = createLineVector(point1=worldOrigin, point2=YAxisNormalize,  name='YAxisNormalize')
  140.     #zNormalCurve = createLineVector(point1=worldOrigin, point2=ZAxisNormalize,  name='ZAxisNormalize')
  141.    
  142.     # Create axis group and move to origin point: visual aid
  143.     #waxisGroup = mc.group([xNormalCurve,yNormalCurve,zNormalCurve], name='{node}_axisGroup'.format(node=node))
  144.    
  145.     # Debugging            
  146.     #print 'XAxisNormalize:', XAxisNormalize.x, XAxisNormalize.y, XAxisNormalize.z
  147.     #print 'YAxisNormalize:', YAxisNormalize.x, YAxisNormalize.y, YAxisNormalize.z
  148.     #print 'ZAxisNormalize:', ZAxisNormalize.x, ZAxisNormalize.y, ZAxisNormalize.z
  149.        
  150.     # pack values into matrix      
  151.     matrix = om.MMatrix()
  152.        
  153.     om.MScriptUtil.setDoubleArray(matrix[0], 0, XAxisNormalize.x) # Sets the first row, first column
  154.     om.MScriptUtil.setDoubleArray(matrix[0], 1, XAxisNormalize.y) # Sets the first row, second column
  155.     om.MScriptUtil.setDoubleArray(matrix[0], 2, XAxisNormalize.z) # Sets the first row, third column
  156.        
  157.     om.MScriptUtil.setDoubleArray(matrix[1], 0, YAxisNormalize.x) # Sets the second row, first column
  158.     om.MScriptUtil.setDoubleArray(matrix[1], 1, YAxisNormalize.y) # Sets the second row, second column
  159.     om.MScriptUtil.setDoubleArray(matrix[1], 2, YAxisNormalize.z) # Sets the second row, third column
  160.        
  161.     om.MScriptUtil.setDoubleArray(matrix[2], 0, ZAxisNormalize.x) # Sets the third row, first column
  162.     om.MScriptUtil.setDoubleArray(matrix[2], 1, ZAxisNormalize.y) # Sets the third row, second column
  163.     om.MScriptUtil.setDoubleArray(matrix[2], 2, ZAxisNormalize.z) # Sets the third row, third column            
  164.        
  165.     # converts inverse matrix to center rotate points to 0
  166.     matrixInverse = matrix.inverse()
  167.        
  168.     # Convert to MTransformationMatrix to extract rotations
  169.     mTransformMtx = om.MTransformationMatrix(matrix)
  170.     mTransformMtxInverse = om.MTransformationMatrix(matrixInverse)
  171.                
  172.     # Get the euler rotations
  173.     eulerRot = mTransformMtx.eulerRotation()
  174.     eulerRotInverse = mTransformMtxInverse.eulerRotation()
  175.        
  176.     # sort to the proper rotate order
  177.     eulerRot.reorderIt(rotOrder)
  178.     eulerRotInverse.reorderIt(rotOrder)
  179.  
  180.     # convert radians to degrees
  181.     rotAngle = [math.degrees(angle) for angle in (eulerRot.x, eulerRot.y, eulerRot.z)]
  182.     rotAngleInverse = [math.degrees(angle) for angle in (eulerRotInverse.x, eulerRotInverse.y, eulerRotInverse.z)]
  183.        
  184.     print 'ANGLES: ', rotAngle
  185.     #print 'ANGLES INVERSE:', rotAngleInverse
  186.        
  187.     #return rotAngleInverse, rotAngle
  188.     return rotAngle
  189.  
  190.  
  191. def createJointControls():
  192.     '''
  193.    @summary:
  194.        creates a joint at the center of every selected edge
  195.    @arguments:
  196.        needs a selection of edges
  197.    @returns:
  198.        JointChain
  199.    '''
  200.  
  201.     # This code works to retain the selected orderd
  202.     selectedEdgeList = mc.ls(orderedSelection=True, long=True)
  203.     #print 'EDGELIST:', selectedEdgeList
  204.    
  205.     # clear the selection
  206.     mc.select(clear=True)
  207.    
  208.     # create a list to store the joints
  209.     jointList = []
  210.    
  211.     numberOfEdges = len(selectedEdgeList)
  212.    
  213.     # for each edge in the list create a joint    
  214.     for index, selectedEdge in enumerate(selectedEdgeList):
  215.        
  216.         # test to make sure you are not on the last edge
  217.         if index < (numberOfEdges - 1):
  218.             # calculate the center of the next edge in the list
  219.             UPDirection = om.MVector(calculateEdgeCenter(selectedEdgeList[index+1]))
  220.         else:
  221.             print "YUP_ DEFAULT"
  222.             UPDirection = om.MVector(0,0,0)
  223.            
  224.                    
  225.         # Main Function
  226.         # get the centerPoint
  227.         edgeCenter = calculateEdgeCenter(selectedEdge)
  228.        
  229.         # get the position of endpoints of the edge
  230.         edgeEndPoints = mc.xform(selectedEdge, query=True, worldSpace=True, translation=True)
  231.        
  232.         point1 = om.MVector(edgeEndPoints[0],edgeEndPoints[1],edgeEndPoints[2])
  233.         point2 = om.MVector(edgeEndPoints[3],edgeEndPoints[4],edgeEndPoints[5])
  234.        
  235.         # determine the point order if point 1 is bigger than point 2
  236.         distance = getDistance(point1, point2)
  237.        
  238.         # determine the magnitude of the difference in points
  239.         direction = distance[0] + distance[1] + distance[2]
  240.        
  241.         # try to determine if the point order for X axis needs to flip
  242.         if direction < 0.0:
  243.             # set the point positions to define the rotation vector
  244.             print "negative Distance"
  245.             #zRot = 0
  246.             originPosition = point1
  247.             XDirection = point2
  248.         else:
  249.             print "positive Distance"
  250.             #zRot = 180
  251.             originPosition = point2
  252.             XDirection = point1
  253.                        
  254.         #UPDirection = om.MVector(0,0,0)
  255.        
  256.         # Main Function
  257.         # get the rotation of the edge based on three points
  258.         rotationAngle = calculateRotations(pointOrigin=originPosition, pointX=XDirection, pointUP=UPDirection)
  259.        
  260.         # create Joint at the edge center and aligned to the edge
  261.         joint = mc.joint(position=edgeCenter, orientation=rotationAngle)
  262.        
  263.         # clear selection so the joints do not attach to one another
  264.         mc.select(clear=True)
  265.        
  266.         #append joint name to list
  267.         jointList.append(joint)
  268.    
  269.     # attach all the joints in a chain    
  270.     createHierarchy(nodeList=jointList)
  271.    
  272.     #newBindSkin " -byClosestPoint -toSkeleton";
  273.        
  274.  
  275. createJointControls()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement