Skip to content

Instantly share code, notes, and snippets.

@BigRoy
Created August 24, 2023 20:09
Show Gist options
  • Save BigRoy/0c00ae92bdabdcc00ea17649660fd81d to your computer and use it in GitHub Desktop.
Save BigRoy/0c00ae92bdabdcc00ea17649660fd81d to your computer and use it in GitHub Desktop.
Maya find meshes with holes in them (that are not watertight) by checking if any edge is a boundary edge (not connected to two faces)
import maya.api.OpenMaya as om
from maya import cmds
def has_boundaries(mesh):
sel = om.MSelectionList()
sel.add(mesh)
dag = sel.getDagPath(0)
it = om.MItMeshEdge(dag)
while not it.isDone():
if it.onBoundary():
return True
it.next()
return False
for mesh in cmds.ls(type="mesh"):
print(mesh, has_boundaries(mesh))
@BigRoy
Copy link
Author

BigRoy commented Aug 24, 2023

Or by doing the edge count check manually:

import maya.api.OpenMaya as om
from maya import cmds

def has_boundaries(mesh):
    sel = om.MSelectionList()
    sel.add(mesh)
    dag = sel.getDagPath(0)
    it = om.MItMeshEdge(dag)
    while not it.isDone():
        if it.numConnectedFaces() < 2:
            return True
        it.next()
    return False
    
    
for mesh in cmds.ls(type="mesh"):
    print(mesh, has_boundaries(mesh))

@BigRoy
Copy link
Author

BigRoy commented Aug 24, 2023

I noticed MFnMesh.getHoles exists but in Maya 2024.1 it always seems to return an empty tuple for me.

Doesn't work.

import maya.api.OpenMaya as om
from maya import cmds

def get_holes(mesh):
    sel = om.MSelectionList()
    sel.add(mesh)
    dag = sel.getDagPath(0)
    fn = om.MFnMesh(dag)
    return fn.getHoles()
    
    
for mesh in cmds.ls(type="mesh"):
    print(mesh, get_holes(mesh))

@BigRoy
Copy link
Author

BigRoy commented Aug 24, 2023

If you allow multiple mesh shells (separate geometry in a single mesh node) to exist but each be watertight the boundary check would still hold. But if you don't allow that you should also check the amount of shells, e.g. maya.cmds.polyEvaluate(mesh, shell=True) != 1. You'd do that before the boundaries check (because it's faster) and that way optimize the query for heavy geometry.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment