Python - Maya group meshes by material within selected group

Python - Maya group meshes by material within selected group

Anonymous
Not applicable
4,342 Views
10 Replies
Message 1 of 11

Python - Maya group meshes by material within selected group

Anonymous
Not applicable

This is a python request I admit... I dunno how to code it.

Suppose you have a list of meshes with arbitrary names within a selected group and you want to merge them by material, but keep the result of each merge within the selected group.

 

From

GroupA

 -mesh(mat1)

 -mesh(mat2)

 -mesh(mat2)

 -...

 

to

 

GroupA

 - merge1 (mat1 meshes)

 - merge2 (mat2 meshes)

 

There may be usage of the material outside the selected group and those shouldn't be involved.

This is challenging because SelectByMaterial grabs the whole scene and Combine chucks meshes out of their current group and requires DeleteHistory to divorce the result from its transforms (left hanging in the wind).

 

 

0 Likes
4,343 Views
10 Replies
Replies (10)
Message 2 of 11

rajasekaransurjen
Collaborator
Collaborator

Hi,

Try This...

import maya.cmds as cmds
rsSl = cmds.ls( sl=1 )
cmds.hyperShade( smn = 1 )
rsSlObjsShdr = cmds.ls( sl=1 )
rsNoOfSlShdr = len(rsSlObjsShdr)

for i in rsSlObjsShdr:
    cmds.hyperShade( o=i )
    rsShdrSl = cmds.listRelatives(allParents=1)
    rsListToCombine = list(set(rsSl) & set(rsShdrSl))

    if(len(rsListToCombine)>1):
        cmds.group(rsListToCombine, n = (i+'_Grp'))
0 Likes
Message 3 of 11

Anonymous
Not applicable

Thanks for the help, but it seems to affect content outside the selected group (if a material is used outside the group).

0 Likes
Message 4 of 11

rajasekaransurjen
Collaborator
Collaborator

can you share the scene file

0 Likes
Message 5 of 11

Anonymous
Not applicable
0 Likes
Message 6 of 11

rajasekaransurjen
Collaborator
Collaborator

hi,

can you attach the file in the post.

0 Likes
Message 7 of 11

Anonymous
Not applicable

here it is

0 Likes
Message 8 of 11

rajasekaransurjen
Collaborator
Collaborator

This will works on the selected objects are in the same group. If we select object from two different groups it will create a new group.

import maya.cmds as cmds
rsSl = cmds.ls( sl=1 )
cmds.hyperShade( smn = 1 )
rsSlObjsShdr = cmds.ls( sl=1 )
rsNoOfSlShdr = len(rsSlObjsShdr)

for i in rsSlObjsShdr:
    cmds.hyperShade( o=i )
    rsShdrSl = cmds.listRelatives(allParents=1)
    rsListToCombine = list(set(rsSl) & set(rsShdrSl))
    cmds.group(rsListToCombine, n = (i+'_Grp'))
0 Likes
Message 9 of 11

Anonymous
Not applicable

 

I assumed we run the python when a Group is selected. Only the meshes within that group should be affected, merged by material.

 

If the python is run with the Mesh selection (inside the group), it sorts and sub-groups them by material, which is great.  But it doesn't merge them (by which I mean Combine and re-add the result to the group). 

 

However, if there's meshes with the same name, like pPlane1 in different groups, they seem to be skipped over (I think).

You can see this is in the test scene, when selecting meshes in MainGroup_2>subgroups_1 (pPlane5,pPlane4,pPlane3) ... nothing happens.

 

So far as I can tell, if different groups have meshes with the same name (pPlane4 in this case), the script doesn't handle that.  But if the script's limit is the selected group, so as to keep everything outside the group unchanged, that'd be better(because within a group meshes cannot have the same name and it protects the rest of the scene).

 

0 Likes
Message 10 of 11

rajasekaransurjen
Collaborator
Collaborator

Hi,

Try this....

import maya.cmds as cmds
rsSl = cmds.ls( sl=1 )
cmds.hyperShade( smn = 1 )
rsSlObjsShdr = cmds.ls( sl=1 )
rsNoOfSlShdr = len(rsSlObjsShdr)
rsObjCmbd = []

for i in rsSlObjsShdr:
    cmds.hyperShade( o=i )
    rsShdrSl = cmds.listRelatives(allParents=1)
    rsSetToCombine = set(rsSl) & set(rsShdrSl)
    rsListToCombine = [k for k in rsSetToCombine]
    if(len(rsListToCombine)>1):
        rsObjCmbd += cmds.polyUnite(rsListToCombine, n = (i+'_Comb') )
    else:
        cmds.group(rsListToCombine, n = (i+'_Comb'))
cmds.delete(rsObjCmbd, ch=True)
0 Likes
Message 11 of 11

Anonymous
Not applicable

The current version kicks the combined result out of the group for multiple meshes (as standard Combine does, leaving it stray in the outliner).

You can test that by choosing MainGroup_2>subgroups_2.

It's a step in the right direction though. You don't have to try more if you don't really want to, but it is interesting.

I think the script's loop needs to pickwalk up to get the groupname of the selected meshes, store that as a variable, then use that variable to re-add the Combined mesh result back where it should go.

It's kind of weird that single meshes can't Combine with anything, so they get put in a group (I guess that's fine, but why not just name rename the single mesh and not nest it?).

 

Notice if you type 'pPlane4' in the outliner, you'll see it in two different groups - the current script still fails to Combine meshes that share the same name (it's interrupted by other groups in the scene above the selection perhaps).

0 Likes