Last active
February 12, 2021 22:53
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 ) ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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 =)