View Full Version : Problems getting object under mouse through API

12 December 2012, 04:13 PM

So this is kinda my first foray into the Maya API world. Mainly used it to get the face being clicked on using closestIntersection. Right now my mouse position is coming in from a draggerCtx in screen space and being converted to world space using viewToWorld from the M3DView class. This is working awesome but the user might not have the mesh selected. The tool is currently being made like an eyedropper and can sample colors from meshes. Took a look and found the selectfromScreen function and it works but sometimes will hit nothing. Any ideas? Should I be looking at MPXContext to get the mouse position? I found a couple of examples using PyQt but thats currently not possible right now. Heres some code and maybe someone has a better way of doing this:

def contextPress():
pressPosition = cmds.draggerContext( 'sampleContext', query=True, anchorPoint=True)
print ("Press: " + str(pressPosition))
# grabbing current 3d view
active_view = mui.M3dView.active3dView()

# Screen position of mouse
x = int(pressPosition[0])
y = int(pressPosition[1])
print x,y

#making my ray source and direction
ray_source = om.MPoint()
ray_direction = om.MVector()

#Converting to world
active_view.viewToWorld(x,y, ray_source, ray_direction)

#get mesh dag path
sel = om.MSelectionList()

#Select from screen
om.MGlobal.selectFromScreen(x,y, om.MGlobal.kReplaceList)
objects = om.MSelectionList()
print objects.length()

#restore selection if there was a selection
#om.MGlobal.setActiveSelectionList(sel, om.MGlobal.kReplaceList)

#Convert from MSelectionList object to string
fromScreen = []

mesh_dag = om.MDagPath()

#cast the ray at the mesh and find out if and where it hits
hit_pnt, face_idx = closest_mesh_intersection(mesh_dag, ray_source, ray_direction)
rayHitPosition = [(hit_pnt.x),(hit_pnt.y),(hit_pnt.z)]

print "HIT AT: " + str(rayHitPosition)
print "FACE AT: " + str(face_idx)


def selectByColorValue(*args):
if(cmds.draggerContext('sampleContext', exists=True)):
cmds.draggerContext( 'sampleContext', pressCommand = "contextPress()", cursor='hand', projection = "s")

def closest_mesh_intersection(mesh_dag, ray_source, ray_direction):
meshFn = om.MFnMesh(mesh_dag)

#Making my Hit Point
hit_point = om.MFloatPoint()

ray_source_float = om.MFloatPoint(ray_source.x, ray_source.y, ray_source.z)
ray_direction_float = om.MFloatVector(ray_direction.x, ray_direction.y, ray_direction.z)

#Pointer nonsense.
face_idx_util = om.MScriptUtil()
face_int_ptr = face_idx_util.asIntPtr()

#Args for closest Interestion
ray_source_float,#const MFloatPoint & raySource,
ray_direction_float,#const MFloatVector & rayDirection,
None, #const MIntArray * faceIds,
None, #const MIntArray * triIds,
False, #bool idsSorted,
om.MSpace().kWorld, #MSpace::Space space,
9999, #float maxParam,
False, #bool testBothDirections,
None, #MMeshIsectAccelParams * accelParams,
hit_point, #MFloatPoint & hitPoint,
None, #float * hitRayParam,
face_int_ptr, #int * hitFace,
None, #int * hitTriangle,
None, #float * hitBary1,
None, #float * hitBary2,
.000001 #float tolerance = 1e-6,

#Again more pointer nonsense. Need to look into this more.
face_idx = face_idx_util.getInt(face_int_ptr)

return (hit_point, face_idx)

EDIT: Fixed. After referencing the marquee tool, I think the default is to use wireframe selection mode though not sure on this but switching it to surface selection mode worked :D

CGTalk Moderation
12 December 2012, 04:13 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.