Maya’s Layout command supports separating overlapping shells as part of the layout process, but I would like to detect the overlapping faces myself and let the artist figure out how to separate them.
Going through each polygon and comparing against every other polygon seems really slow… might there be something in the API that could help, or maybe some solution that is already floating around?
Thanks.
it’s not that slow, if you just want the tool to do something like find overlapping shells and select them, assuming you aren’t looking to go more detailed then the shell bounds
compare each shell bound, if bounds overlap then select
def selectOverlappingShells(sel=None):
import maya.cmds as cmds
if not sel:
sel=cmds.ls(sl=True)
if not sel:
return "nothing selected or passed"
currentTool=cmds.currentCtx()
cmds.setToolTo('selectSuperContext')
biglist=cmds.ls( cmds.polyListComponentConversion( sel, tf=True ) , fl=True )
shells=[]
while len(biglist) > 0:
cmds.select( biglist[0], r=True )
cmds.polySelectConstraint(t=0)
cmds.polySelectConstraint(sh=1,m=2)
cmds.polySelectConstraint(sh=0,m=0)
aShell=cmds.ls( sl=True, fl=True )
shells.append( aShell )
biglist=list( set(biglist) - set(aShell) )
cmds.setToolTo(currentTool)
cmds.select(clear=True)
#shells = [ [faces in uv shell 1], [faces in shell 2], [etc] ]
bounds=[]
for faces in shells:
uv=cmds.polyEditUV( cmds.polyListComponentConversion( faces, ff=True, tuv=True), q=True )
uMin=uv[0]
uMax=uv[0]
vMin=uv[1]
vMax=uv[1]
for i in range(len(uv)/2):
if uv[i*2]<uMin: uMin=uv[i*2]
if uv[i*2]>uMax: uMax=uv[i*2]
if uv[i*2+1]<vMin: vMin=uv[i*2+1]
if uv[i*2+1]>vMax: vMax=uv[i*2+1]
bounds.append( [[uMin,uMax],[ vMin,vMax]] )
overlappers=[]
for a in range(len(shells)):
for b in range(a):
aL=bounds[a][0][0]
aR=bounds[a][0][1]
aT=bounds[a][1][1]
aB=bounds[a][1][0]
bL=bounds[b][0][0]
bR=bounds[b][0][1]
bT=bounds[b][1][1]
bB=bounds[b][1][0]
overlaps=True
if aT<bB: #A entirely below B
overlaps=False
if aB>bT: #A entirely above B
overlaps=False
if aR<bL: #A entirely right of B
overlaps=False
if aL>bR: #A entirely left of B
overlaps=False
if overlaps:
overlappers.extend(shells[a])
overlappers.extend(shells[b])
if overlappers:
cmds.select(overlappers, r=True)
Thanks for the example. I do need to detect overlaps at the triangle level.
I ended up dividing UV space into a grid where the size of each cell is the average size of a triangle in UV space. I then put UVs into each tile they cross over.
Then i go through each tile and compare all the triangles against all the other triangles in the tile and do a “is this UV inside the UVs of another triangle” test, and perform a Line Intersection test.
This tells me if the UVs for 1 triangle overlap the UVs of another triangle. Its really slow (written in python) for large objects and only works on Triangulated Meshes.
To speed up the process I may subdividing tiles into sub-tiles if there are a large number of small triangles inside a single tile, or just kick the script over to programming to get it turned into a compiled plugin.