Skip to content

Instantly share code, notes, and snippets.

@whoiscarlo
Created February 15, 2017 21:06
Show Gist options
  • Save whoiscarlo/97fd93a1f26228d86d4e8e4666be0f8e to your computer and use it in GitHub Desktop.
Save whoiscarlo/97fd93a1f26228d86d4e8e4666be0f8e to your computer and use it in GitHub Desktop.
This script is designed to return ALL nearby vertices inside the selection sphere, whereas you are only looking for whole objects. So you could short circuit this code to continue on to the next object once you have a single matching vertex. (Which should speed up your check by several times for mostly enclosed objects with a large number of verts.
# Origin http://forums.cgsociety.org/archive/index.php?t-904223.html
import maya.OpenMaya as api
import maya.cmds as cmds
def findNearby(point, tolerance):
'''findNearby
point - Either an MPoint, a tuple (x, y, z), or an object name (Uses that objects pivot)
tolerance - The search radius for finding nearby selection
'''
mode = 'vertex'
#convert an object to an API point (Get it's worldspace position)
if isinstance(point, basestring):
point = pointFromObject(point)
point = Point(point)
meshList = buildMeshList()
selection = api.MSelectionList()
for mesh in meshList:
matrix = api.MMatrix(mesh.inclusiveMatrix())
meshObj = api.MFnMesh(mesh)
meshBB = meshObj.boundingBox()
meshBB.transformUsing(matrix)
pointBB = api.MBoundingBox(
Point(point.x-tolerance, point.y-tolerance, point.z-tolerance),
Point(point.x+tolerance, point.y+tolerance, point.z+tolerance))
#if the mesh is inside the bounding box for the point+tolerance
if meshBB.contains(point) or meshBB.intersects(pointBB):
if mode in ['vertex', 'cv', 'point']:
iter = api.MItGeometry(mesh)
while not iter.isDone():
vert = iter.position(api.MSpace.kWorld)
if pointBB.contains(vert):
if (point-vert).length()<tolerance:
selection.add(mesh, iter.currentItem())
iter.next()
else:
pass
matching = []
selection.getSelectionStrings(matching)
return matching
def buildMeshList():
meshList = []
iter = api.MItDag(api.MItDag.kDepthFirst, api.MFn.kMesh)
while not iter.isDone():
dagPath = api.MDagPath()
iter.getPath(dagPath)
dagPath.extendToShape()
if not dagPath.fullPathName().endswith('Orig'):
meshList.append(dagPath)
iter.next()
return meshList
#DEPS#
class Point(api.MPoint, object):
'''Subclass of MPoint, use a nicer str() and repr()'''
def __init__(self, x=0, y=0, z=0):
#allow point to take a single tuple, or 3 floats, or wrap an existing MVector
if isinstance(x, api.MPoint) or isinstance(x, api.MVector):
super(Point, self).__init__(x)
return
if isinstance(x, tuple) or isinstance(x, list):
super(Point, self).__init__(x[0], x[1], x[2])
else:
api.MPoint.__init__(self, x, y, z)
def __str__(self):
return '(%g, %g, %g)'%(self.x, self.y, self.z)
def __repr__(self):
return '<<MPoint (%g, %g, %g)>>'%(self.x, self.y, self.z)
def asTuple(self):
return (self.x, self.y, self.z)
def pointFromObject(object):
'''Get an objects xform, return Point object'''
pos = cmds.xform(object, q=True, ws=True, t=True)
return Point(pos[0], pos[1], pos[2])
findNearby('pSphere1', 1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment