Posts Tagged ‘ uninstance

Uninstance all instances in a Maya scene

From over on my mel wiki:

Maya makes it easy to create an instance of a node, but I’ve found no built-in way to query what nodes in the scene are instanced.  Poking around a bit in the API however, it only takes a few lines of code:

# Python code
import maya.cmds as mc
import maya.OpenMaya as om

def getInstances():
    instances = []
    iterDag = om.MItDag(om.MItDag.kBreadthFirst)
    while not iterDag.isDone():
        instanced = om.MItDag.isInstanced(iterDag)
        if instanced:
            instances.append(iterDag.fullPathName())
        iterDag.next()
    return instances

This function will return a list of all the instances in the scene, nice! I have yet to find any other function that can do this via mel.

But how would you actually uninstance them? I worked on this problem quite a bit: If you simply have a bunch of leaf nodes that are instanced, it’s not hard to do. But if you have a say ten spheres all instanced, then you make two groups of five, then instance those groups, and parent all the groups, then instance that parent… very quickly things get hairy:  You try and uninstance a leaf by duplicating it, and now the duplicate appears in every other parental instance!
Like I just mentioned, most solutions I’ve found explain you can just ‘duplicate the instance’ to solve this problem, and this works on an individual instance that has no parent node that is an instance.  But when you have the situation I list above, the solution I found is this:  You can actually duplicate the instances parent, then delete the original parent, which will (via a loop) cleanly uninstance everything in the scene.  And since the getInstances() function returns a list parent-first, this works out great:

def uninstance():
    instances = getInstances()
    while len(instances):
        parent = mc.listRelatives(instances[0], parent=True, fullPath=True)[0]
        mc.duplicate(parent, renameChildren=True)
        mc.delete(parent)
        instances = getInstances()