Skip to content

Instantly share code, notes, and snippets.

@SEVEZ
Last active February 12, 2021 22:53
Show Gist options
  • Save SEVEZ/191d2e6cb9498c4b2961 to your computer and use it in GitHub Desktop.
Save SEVEZ/191d2e6cb9498c4b2961 to your computer and use it in GitHub Desktop.
Attach meshes to last selected, keeping pivots, transforms and hierarchy. Remake of script by Thomas Hamilton from here http://www.creativecrash.com/maya/script/attachmaster #WIP
import maya.cmds as mc
import string
def PS_Attach( objs ):
def dag_par( obj ):
if isinstance( obj, basestring ):
return string.join( mc.listRelatives( obj, pa=1, f=1 )[0].split('|')[:-1], '|' )
pre_sel = None
if objs:
pre_sel = mc.ls( objs, tr=1, l=1 )
else:
pre_sel = mc.ls( sl=1, tr=1, l=1 )
sel = []
for s in pre_sel:
if mc.filterExpand( mc.listRelatives( s, s=1, pa=1, f=1 ), sm=12 ): sel.append( s )
if sel:
if len( sel ) < 2 :
mc.error( 'Select at least two polygon objects!' )
else:
mc.error( 'No polymeshes selected!' )
par = dag_par( sel[-1] ) # store last mesh dag path
origname = par.split('|')[-1] # store short name of last mesh
mat = mc.xform( par, q=1, ws=1, m=1 ) # store transform of last mesh
rpvt = mc.xform( par, q=1, ws=1, rp=1 )
spvt = mc.xform( par, q=1, ws=1, sp=1 )
dd = [] # find any selected meshes above last in hierarchy
for s in sel[:-1]:
pd = dag_par( s )
if par.find( pd ) != -1 and par != pd : dd.append( pd )
if dd: # get topmost mesh above last
min = 999
new_par = None
for s in dd:
l = len( s.split('|') )
if l < min :
min = l
new_par = s
par = new_par
par = dag_par( par ) # swap last and topmost
id = sel.index( par )
if id:
tmp = sel[ id ]
sel[ id ] = sel[ -1 ]
sel[ -1 ] = tmp
chn = [] # children to unparent
sel = [ s.split('|')[-1] for s in sel ] # convert dag to short names
par = string.join( par.split('|')[:-1], '|' ) # parent of output mesh
for s in sel:
shapes = mc.listRelatives( s, s=1, pa=1 ) # remove extra shapes
if len( shapes ) > 1 :
mc.delete( shapes[1:] )
ch = mc.listRelatives( s, c=1, typ='transform' ) # unparent all children from selected meshes
if ch :
for c in ch:
if not c in sel:
chn.append( c )
mc.parent( c, w=1 )
if mc.listRelatives( s, p=1 ) :
mc.parent( s, w=1 ) # unparent all selected meshes
nullGrp = mc.group( em=1 ) # Null group to handle transform
mc.xform( nullGrp, ws=1, m=mat )
comb = mc.polyUnite( sel, ch=0 ) # Merge meshes
mc.xform( comb, ws=1, rp=rpvt ) # restore transform
mc.xform( comb, ws=1, sp=spvt )
mc.parent( comb, nullGrp )
mc.makeIdentity( comb, a=1, t=1, r=1, s=1, n=0 )
mc.parent( comb, w=1 )
mc.delete( nullGrp )
if par : mc.parent( comb, par ) # Parent everything back
if chn : mc.parent( chn, comb )
mc.select( mc.rename( comb, origname ), r=1 )
mc.setAttr( origname + '.displayRotatePivot', 1 )
mc.setAttr( origname + '.displayScalePivot', 1 )
PS_Attach( mc.ls( sl=1 ) )
@Bangruu
Copy link

Bangruu commented Feb 12, 2021

Hi there,
The script is very handy, thanks a lot!
I have just one idea- is it possible to add ability to combine instance-type meshes, without breaking up connection between them?
I mean, in 3ds max and blender it's works just by default- you can easily attach some new geometry parts to one of the instances and all other will update permanently; but in maya if you try to attach some new mesh to one of the instance-type object all other instances just disappear =)

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