Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
On Maya click: 2d coordinates to 3d world coordinates
import maya.api.OpenMaya as om
import maya.api.OpenMayaUI as omui
import maya.cmds as cmds
# Maya Python API:
# http://help.autodesk.com/view/MAYAUL/2017/ENU/?guid=__py_ref_index_html
def onPress():
"""Take x,y from mouse click, convert into 3d world coordinates"""
vpX, vpY, _ = cmds.draggerContext(ctx, query=True, anchorPoint=True)
position = om.MPoint() # 3D point with double-precision coordinates
direction = om.MVector() # 3D vector with double-precision coordinates
# This takes vpX and vpY as input and outputs position and direction
# values for the active view.
# - M3dView: provides methods for working with 3D model views
# - active3dView(): Returns the active view in the form of a class
# - viewToWorld: Takes a point in port coordinates and
# returns a corresponding ray in world coordinates
omui.M3dView().active3dView().viewToWorld(
int(vpX),
int(vpY),
position, # world point
direction) # world vector
for mesh in cmds.ls(type='mesh'):
# Create a list which can hold MObjects, MPlugs, MDagPaths
selectionList = om.MSelectionList()
selectionList.add(mesh) # Add mesh to list
dagPath = selectionList.getDagPath(0) # Path to a DAG node
fnMesh = om.MFnMesh(dagPath) # Function set for operation on meshes
# Find the closest intersection with the mesh and of a ray (starting
# at raySource and travelling in rayDirection).
# The maxParam and testBothDirections flags can be used to control
# the radius of the search around the raySource point.
intersection = fnMesh.closestIntersection(
om.MFloatPoint(position), # raySource
om.MFloatVector(direction), # rayDirection
om.MSpace.kWorld, # space
99999, # maxParam
False) # testBothDirections
# Extract the different values from the intersection result
hitPoint, hitRayParam, hitFace, hitTriangle, \
hitBary1, hitBary2 = intersection
# Extract x, y, z world coordinates of the hitPoint result
x, y, z, _ = hitPoint
if (x, y, z) != (0.0, 0.0, 0.0):
print(x, y, z) # Print the world coordinates
# Name of dragger context
ctx = 'Click2dTo3dCtx'
# Delete dragger context if it already exists
if cmds.draggerContext(ctx, exists=True):
cmds.deleteUI(ctx)
# Create dragger context and set it to the active tool
cmds.draggerContext(ctx, pressCommand=onPress, name=ctx, cursor='crossHair')
cmds.setToolTo(ctx)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment