Aligning axis of rotation with vector in Maya

How to do I change the center pivot of a mesh, so that it rotates the mesh in the direction of a given vector?

The quick’n-dirty is just to use an aim constraint and then delete it. However you need to figure out what to do about the second axis, or you’ll get random flips if your target goes too high.

Is there a way to do it in Python?

[QUOTE=Theodox;18364]The quick’n-dirty is just to use an aim constraint and then delete it. However you need to figure out what to do about the second axis, or you’ll get random flips if your target goes too high.[/QUOTE]



import maya.cmds as cmds
def aim_node (obj_to_align, target_pos, aim_vect  = [1,0,0] , up_vect =[0,1,0]):
    '''aim supplied object at supplied world space position
    @param obj_to_align -- maya transform node
    @param target pos -- [x,y,z] world position to aim at
    @optional param  aim_vect -- local axis to aim at the target position
    @optional param  up_vect -- secondary axis aim vector
     '''

   
    tgt = cmds.createNode('transform')  # looks like locator version doesn't work on maya 2012+
    cmds.xform(tgt, t=target_pos, a=True)
    cmds.select(tgt, obj_to_align)
    const = cmds.aimConstraint( aim=aim_vect, worldUpVector = up_vect, worldUpType = "vector")    
    cmds.delete( const, tgt)
    
    
aim_node ('pCube1', [100, 100,5] )

[QUOTE=Theodox;18366]



import maya.cmds as cmds
def aim_node (obj_to_align, target_pos, aim_vect  = [1,0,0] , up_vect =[0,1,0]):
    '''aim supplied object at supplied world space position
    @param obj_to_align -- maya transform node
    @param target pos -- [x,y,z] world position to aim at
    @optional param  aim_vect -- local axis to aim at the target position
    @optional param  up_vect -- secondary axis aim vector
     '''

   
    tgt = cmds.spaceLocator(p=target_pos)
    cmds.select(tgt, obj_to_align)
    const = cmds.aimConstraint( aim=aim_vect, worldUpVector = up_vect, worldUpType = "vector")    
    cmds.delete( const, tgt)
    
    
aim_node ('pCube1', [100, 100,5] )

[/QUOTE]

Hmm…maybe I’m not asking the right question. So here’s my problem. I have a bunch of meshes with their center pivots all messed up after I froze their transformations. I’m hoping to rotate the axis so that my up vector follows the normal of the surface. I’m using cmds.polyNormalPerVertex( query=True, xyz=True ) to find the normal vector and I was hoping to use cmds.xform( mesh, ra=[x, y, z]) to change the value of the rotation.

xform -ra will reorient the local axis but will un-zero your rotations as well (and in suprising ways, since its going euler-quaternion-euler during the transformation. If all you care about is having local axes that point the right way it’ll be fine – if you care about the actual rotation channel values it will be wonky.

PS - if you’ve got the normal vector, you can get a viable target position by just adding that vector to the position of the object…

PPS (edit)


def rotate_ax (obj, tgt):
    ''' 
    aim transform <obj> at world space point <tgt>.  All rotations in rotated channel, geometry is transformed so it does not appear to move during this transformation
    '''
    aim_node ( obj, tgt)  # that's the def from earlier example
    wim = cmds.getAttr(obj + '.worldInverseMatrix')
    cmds.xform(obj + ".vtx[li]", matrix=wim)[/li]    pos = cmds.xform(obj, q=True , t=True, a=True, ws=True)
    cmds.xform(obj + ".vtx[li]",  t=pos, r=True, ws=True)[/li]