Skip to content

Instantly share code, notes, and snippets.

@patwooky
Last active October 31, 2016 10:25
Show Gist options
  • Save patwooky/0c8f289dd764f9a327d74e4bf6f09def to your computer and use it in GitHub Desktop.
Save patwooky/0c8f289dd764f9a327d74e4bf6f09def to your computer and use it in GitHub Desktop.
This Maya tool deletes all shape nodes from the a list of selection, and replaces those shapes with the shape node of the last selected object, turning all objects into instances of the last object
'''
---
Duplicates to Instances
version: v01_04
date: 20161031
Written by: Patrick Woo
[email protected]
---
Description:
This tool takes a list of objects, use the shape node of the last selected object,
and turn it into an instance to the rest of the objects in the list.
changelog:
- using str values for names and paths, and PyNode() to refer to scene objects
only at the point of need
'''
from pymel.core import *
import maya.mel as mm
infoStr = '''
---
Duplicates to Instances
version: v01_04
date: 20161031
Written by: Patrick Woo
[email protected]
---
Description:
This tool takes a list of objects, use the shape node of the last selected object,
and turn it into an instance to the rest of the objects in the list.
'''
def parseLongName(longNameIn):
'''
takes a maya long name (full path) as a str and returns the path and name as strings
longNameIn - <str> example: u'|streamerConstruction_grp|waistStreamerConstruct_grp'
return - <dict> {'path': <str>path, 'name': <str>shortName}
'''
path = longNameIn[:longNameIn.rfind('|')] # longNameIn up to the last '|'
shortName = longNameIn[longNameIn.rfind('|')+1:] # from the last '|' to the rest of longNameIn
return {'path': path, 'name': shortName}
def dupsToInstances(sel):
'''
this tool deletes all shape nodes from the a list of selection,
and replaces those shapes with the shape node of the last selected object,
turning all objects into instances of the last object
the tool assumes that for each of the instances there are no further group hierarchies
parented under them.
'''
gMainProgBar = mm.eval('$tmp = $gMainProgressBar') # get main progress bar
progressBar(gMainProgBar, e=True, endProgress=True)
msgNoShapes = 'Please select objects with shape nodes before running the script. Aborted'
if not sel:
print 'dupsToInstances:', msgNoShapes
return
shapesList = []
for x in sel:
adShapesList = listRelatives(x, ad=True, type='shape')
if adShapesList:
shapesList += [i for i in adShapesList if i not in shapesList]
elif 'shape' in nodeType(x, i=True):
shapesList += list(x) if x not in shapesList else [] # putting x in a list is intentional
shapesList = [i.name() for i in listRelatives(sel, ad=True, type='shape')]
if not shapesList:
print 'dupsToInstances:', msgNoShapes
return
if len(shapesList) < 2:
msgNotEnoughObjs = 'Please select more than one object to make them instances. Aborted'
print 'dupsToInstances:', msgNotEnoughObjs
return
# all prerequisites fulfilled
try:
timer(n='dupsToInstanceTimer', e=True) # in case the timer was previously started
except:
pass
lastObjName = PyNode(shapesList[-1]).getParent().name()
mainTransform = duplicate(PyNode(shapesList[-1]))[0]
parent(mainTransform, None)
# print 'mainshape is', mainTransform
mainShape = mainTransform.getShape()
# print 'mainshape is', mainShape
xformList = [PyNode(x).getParent().name() for x in shapesList]
print 'dupsToInstances: selection has %i objects, %i shape nodes' % (len(shapesList), len(xformList))
timer(n='dupsToInstanceTimer', s=True) # start timer
gMainProgBar = mm.eval('$tmp = $gMainProgressBar') # get main progress bar
progAmt = 0
progressBar(gMainProgBar, e=True, beginProgress=True,
maxValue=len(xformList), isInterruptable=True)
totalLenNumObjs = len(xformList)
newXformList = []
# delGrp = group(name='toBeDeleted_grp', empty=True)
timing = 0 # stores the time taken for dupsToInstanceTimer
while xformList:
# print 'dupsToInstances: xformList (len %i) is %s' % (len(xformList), xformList)
obj = PyNode(xformList[0])
tmpObj = duplicate(mainTransform, instanceLeaf=True)[0] # duplicate as instance
parent(tmpObj, obj.getParent())
xform(tmpObj, ws=True, a=True, m=xform(obj, q=True, ws=True, a=True, m=True))
assumeName = obj.name()
obj.rename(obj.name()+'_toDelete')
# print 'dupsToInstances: ori obj renamed to', obj.name()
tmpObj.rename(assumeName)
# print 'dupsToInstances: tmpObj renamed to', tmpObj.name()
if len(xformList) >= 1:
xformList = xformList[1:]
shapesList = shapesList[1:]
else:
xformList = []
shapesList = []
# print 'dupsToInstances: pre-delete', obj
delete(obj)
del obj
newXformList.append(tmpObj.name())
# print 'dupsToInstances: newXformList (len %i) is %s' % (len(newXformList), newXformList)
progressBar(gMainProgBar, e=True, step=1,
status='processing %s. %s out of %s.' % (newXformList[-1], progAmt, totalLenNumObjs) )
if progressBar(gMainProgBar, q=True, isCancelled=True):
print 'dupsToInstances: Operation aborted & incomplete. Converted %i out of %i to instances. UNDO IS RECOMMENDED.' % (progAmt, len(xformList))
progressBar(gMainProgBar, e=True, endProgress=True)
timing = timer(n='dupsToInstanceTimer', e=True)
# break
return
if progAmt > totalLenNumObjs:
progressBar(gMainProgBar, e=True, endProgress=True)
timing = timer(n='dupsToInstanceTimer', e=True)
break
progAmt += 1
# end for obj
progressBar(gMainProgBar, e=True, endProgress=True)
# if progressBar(gMainProgBar, q=True, progress=True) >= progressBar(gMainProgBar, q=True, maxValue=True):
# progressBar(gMainProgBar, e=True, endProgress=True)
# break
if timing == 0:
timing = timer(n='dupsToInstanceTimer', e=True)
# delete(delGrp)
select(newXformList, replace=True)
print 'dupsToInstances: operation finished in %0.2fs (%0.2fmins)' % (timing, timing/60.0)
print 'dupsToInstances: %i objects have been converted to instances of %s' % (len(ls(sl=True)), lastObjName)
delete(mainTransform)
del xformList, shapesList
print ''
return
print infoStr
dupsToInstances(ls(sl=True))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment