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()

Reply via email to