this code might be useful example for you. Im working on a similar thing. I want to re-orient a polygon if extracted from a mesh based on the angle of the face. Or if you have some model that has lost its transforms because of a lattice or vertex deformation.
I think if you only use the face normal you might get a twisting problem. In this case I use 3 points in space to define the angle of the plane. The points are selected somewhat arbitrary for now. I could't really think of a good way to define the three points. You could probably do a vertex selection order, but unfortunately I don't think you can get the selected order of components very easily. -- You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group. To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsubscr...@googlegroups.com. To post to this group, send email to python_inside_maya@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
#=============================================================================== # Convert To Worldspace Transforms # author: Bradon Webb # bra...@paraportable.net # 01/08/13 # # This script will calculate world space rotation and transformation to an polygon object # that has lost its transformation and rotation. # Based on a the zero index polygon face and vertex 0, 1, 2 # 0 = origin # 1 = X axis # 2 = Up axis # # Select your object or polygon, then run script. # #=============================================================================== import maya.cmds as mc import math import maya.OpenMaya as om import maya.mel as mel import pymel.core as pm 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 @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 calculateFaceCenter(nodeName='nodeName', faceNum=0): ''' @summary: gets the worldspace center given a nodeName and a face centerpoint is based on average weigting or the same as the blue dot on the face libraries pymel, openMaya @arguments: nodeName = string of a node name faceNum = Int face number @returns: worldspace XYZ coordinates of the face as a [list], [x,y,z] ''' # format node name with face num, store as pymel face face = pm.MeshFace('{node}.f[{num}]'.format(node=nodeName, num=faceNum)) # get centerpoint of face pt = face.__apimfn__().center(om.MSpace.kWorld) centerPoint = pm.datatypes.Point(pt) print 'CENTERPOINT: ', centerPoint return centerPoint def calculateRotations(pointOrigin=0, pointX=1, pointUP=2, nodeName='nodeName'): ''' @summary: calculates Euler rotation values from a node and 3 points @arguments: pointOrigin = number of the point for the origin pointX = number of the point for the X axis pointUP = number of the point for the Y Axis nodeName = the name of the geo to query the points from @returns: Euler rotation to UNnrotate the object, Euler rotation to rotate the object back [[x,y,z],[x,y,z]] ''' node = nodeName rotOrder = mc.getAttr('%s.rotateOrder'%node) print 'ROTORDER:', rotOrder # Get Point Positions originPosition = om.MVector(*mc.pointPosition('{mesh}.vtx[{vertex}]'.format(mesh=node, vertex=pointOrigin), world=True)) XDirection = om.MVector(*mc.pointPosition('{mesh}.vtx[{vertex}]'.format(mesh=node, vertex=pointX), world=True)) UPDirection = om.MVector(*mc.pointPosition('{mesh}.vtx[{vertex}]'.format(mesh=node, vertex=pointUP), world=True)) 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 def findWorldSpaceTransforms(): ''' @summary: re-center an objects pivot and give the proper worlspace translation and rotation values to a selected poly plane uses calculateFaceCenter and calculateRotations functions @arguments: none @returns: none ''' # Get a list of selected nodes selectedNodes = mc.ls(selection=True, long=True) # for each node selected for node in selectedNodes: # freeze transforms, to ensure all rotations positions will be applied properly mc.makeIdentity(node, apply=True, translate=True, rotate=True, scale=True) # calculate the center point of the object's face centerPoint = calculateFaceCenter(nodeName=node) # move pivots to center of face mc.move(centerPoint[0],centerPoint[1],centerPoint[2], '{node}.rotatePivot'.format(node=node), rotatePivotRelative=True) mc.move(centerPoint[0],centerPoint[1],centerPoint[2], '{node}.scalePivot'.format(node=node), scalePivotRelative=True) # Move object to the origin mc.move(0.0, 0.0, 0.0, node, rotatePivotRelative=True) # calculate objects rotaion # ARGS (pointOrigin=0, pointX=1, pointUP=2 nodeName=node) nodeRotations = calculateRotations(pointOrigin=0, pointX=1, pointUP=2, nodeName=node) # Set Variables for rotations unRotateNode = nodeRotations[0] rotateNode = nodeRotations[1] # unRotate object to world UP mc.rotate(unRotateNode[0], unRotateNode[1], unRotateNode[2], node) # freeze transforms, to ensure all rotations positions will be applied properly mc.makeIdentity(node, apply=True, translate=True, rotate=True, scale=True) # rotate and move node to original rotation mc.rotate(rotateNode[0], rotateNode[1], rotateNode[2], node) mc.move(centerPoint[0],centerPoint[1],centerPoint[2], node, rotatePivotRelative=True) #mc.spaceLocator(name='center', position=centerPoint) # run main function findWorldSpaceTransforms()