Get all Construction History Nodes in a file

Is anyone aware of an internal MEL/Python command or flag that will return all Nodes that would be counted as “Polygon Construction History”?
Nodes like “polySplit” or “polyMapSewMove”?

This is what I am currently doing:


constructionHistoryNodes = [
        'polySplit', 'deleteComponent', 'polyAutoProj', 'polyCollapseEdge', 
        'polyDelEdge', 'polyExtrudeFace', 'polyMergeVert', 'polyMoveFace', 
        'polySoftEdge', 'polySplitRing', 'polyMapSewMove', 'polyColorPerVertex', 
        'polyTweak', 'materialInfo', 'polyAppend', 'polyBevel', 'polyBridgeEdge', 
        'polyCloseBorder', 'polyCreateFace', 'polyCube', 'polyCut', 
        'polyCylinder', 'polyExtrudeEdge', 'polyMapDel', 'polyNormalPerVertex', 
        'polyPlanarProj', 'polyPlane', 'polyPoke', 'polySplitVert', 
        'polySubdEdge', 'polyTriangulate', 'polyTweakUV', 'transformGeometry', 
        'rigidSolver', 'groupId', 'groupParts', 'polyColorMod', 'blendColorSets', 
        'polyNormal', 'polyUnite', 'polyChipOff', 'polySeparate']

historicalNodes = list(set(cmds.ls(type=constructionHistoryNodes)))

Obviously this has problems because the list may not be complete. But if i had a way to get all the nodes, I wouldn’t need the list in the first place! :slight_smile:

The reason I need this information is because we have Maya files where there exists a large number of these nodes that are orphaned, i.e. no longer part of a construction history chain. Maya’s native Optimize Scene Size does not catch and remove these nodes, so i am looking for them myself.

Hey there,

You can probably do:

import maya.cmds as cmds

# Get all nodes registered in maya
allNodes = cmds.allNodeTypes()

# Typically, maya's default poly nodes inherit from polyBase.  Get just those
polyNodes = cmds.nodeType('polyBase', itn=True, d=True)

For the “delete…” commands, those derive from ‘node’, so you might need to explicitly include those.

Most nodes have a “isHistoricallyInteresting” attribute that indicates if it should be considered construction history (IIRC). You could also use that as a check. Hope that gives you some direction.
-J

Also, if you’re looking for nodes couldn’t you look for those nodes that don’t have any output connections?

the ls command respects inheritance, so you can try cmds.ls(type=‘polyBase’) or cmds.ls(type=‘polyModifier’) depending on what you want. The node documentation will show you the base classes.

thanks for the help guys!

Oh sweet. I didn’t realize a lot of functions that have a -type flag respect inheritance, or think to look for that in the node documentation.

Now I just wish there was a way to use shader classifications with the -type flag.

Could you use the results of “listNodeTypes” as an input into the -types flag of the “ls” command?


import maya.cmds as cmds
classification = 'shader'
nodeTypes = cmds.listNodeTypes(classification)
validNodes = cmds.ls(type=nodeTypes)

Ha, somehow I never knew that you could pass a list to a -type flag :/. Thanks!

Perhaps somewhat unrelated to the conversation but still relevant to the title of the thread, if you’ve got references with history on them, be it animation or poly editing, you can export a so called “offline” file via the reference editor. That will give you a .ma file with just the history on that reference which could then be imported back onto a similar reference.

[QUOTE=jtilden20;20510]Also, if you’re looking for nodes couldn’t you look for those nodes that don’t have any output connections?[/QUOTE]

In my case I have complete history chains with no output mesh. So i am walking the connections to the end to see if a valid mesh exists. If not, I gather up all the nodes in the orphaned chain and remove them.


def dangling_history_nodes():
    for item in cmds.ls(type="polyBase"):
        if not cmds.listConnections(item + ".output"):
            yield cmds.listHistory(item)

Potential side issue: if you have nodes that have shared output - so they are part of a valid history as well as an invalid one - this won’t know them.

when i examine these orphan strands of construction history there are all kinds of edge cases to handle, it’s a little more complicated than just no outputs.

for example, there are groupID and groupPart nodes to consider, also connections to objectSets and renderSets (isolateSelect loves to leave behind tons of objectSets).

So i start with a node, say, “polyPoke345”, check for outputs, if none, mark for deletion. If some connections, check if one is a non-intermediate mesh, if so, skip to the next node. If none are meshes, recursively scan all the connections. if no non-intermediate mesh is found, delete all the nodes marked along the way.

maybe the brute force approach is to get the history chain for all the dead nodes, as above, then the history chain for all the valid meshes., then remove any nodes in the valid history from the kill list.