Last active
January 9, 2025 13:00
-
-
Save fredrikaverpil/731e5d43c35d6372e19864243c6e0231 to your computer and use it in GitHub Desktop.
On Maya click: 2d coordinates to 3d world coordinates
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
@cgside hi there. It was a long time ago I wrote this script and I no longer have access to Maya, so I unfortunately cannot help you.
add these codes under line "# Extract the different values from the intersection result":
if not intersection:
continue
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey there. Thank you for this. I am having a problem with your code, with a simple scene with a few cubes I get the error:
Error: cannot unpack non-iterable NoneType object
Traceback (most recent call last):
File "", line 49, in onPress
TypeError: cannot unpack non-iterable NoneType object #
Do I need to update the code somehow? Thank you