Skip to content

Instantly share code, notes, and snippets.

@mstevenson
Created November 25, 2012 22:40
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save mstevenson/4145716 to your computer and use it in GitHub Desktop.
Save mstevenson/4145716 to your computer and use it in GitHub Desktop.
Maya MEL script that breaks up a mesh based on materials. Created by Andrew Coggeshall at Basenji Games.
// Poly Separate
// Copyright (C) 2012 Basenji Games
// Licensed under the MIT license
string $selection[] = `ls -sl`;
sepMat($selection[0]);
global proc sepMat(string $object){
string $shadingGroups[] = getSGsFromShape($object);
string $ParentName = ($object + "_lightMap_Group");
group -empty -n $ParentName;
for ($i = 0; $i < size($shadingGroups) ; $i = $i + 1)
{
string $theMaterial[] = `listConnections -d off -s on $shadingGroups[$i]`;
string $clone = ($object + "_" + $theMaterial[0]);
duplicate -n $clone $object;
parent $clone $ParentName;
string $material[] = `listConnections -d off -s on $shadingGroups[$i]`;
select $clone; ConvertSelectionToFaces;
string $tempset = `sets`;
string $tempgrps[] = `listConnections -type shadingEngine $material[0]`;
select `sets -int $tempset $tempgrps[0]`;
InvertSelection;
delete;
}
delete $object;
}
proc string[] getSGsFromShape( string $shape )
{
string $myShapeNode[] = `listRelatives -children -shapes $shape`;
string $shadingEngines[];
if ( `objExists $shape` )
{
string $dest[] = `listConnections -destination true -source false
-plugs false -type "shadingEngine" $myShapeNode[0]`;
if ( size( $dest ) )
{
string $select[] = `ls -sl`;
select -r -ne $dest;
$shadingEngines = `ls -sl`;
select -r $select;
}
}
return $shadingEngines;
}
@viliusddd
Copy link

amazing!

@Dariusz1989
Copy link

Epic, can we get python version? :- D

@GuyMicciche
Copy link

GuyMicciche commented Sep 20, 2021

from maya import cmds

def getSGsFromShape(shape):

myShapeNode=cmds.listRelatives(shape, shapes=1, children=1)
shadingEngines = []
if cmds.objExists(shape):
	dest=cmds.listConnections(myShapeNode[0], 
		source=False, 
		plugs=False, 
		destination=True, 
		type="shadingEngine")
	if len(dest):
		select=cmds.ls(sl=1)
		cmds.select(dest, r=1, ne=1)
		shadingEngines=cmds.ls(sl=1)
		cmds.select(select, r=1)
		
	
return shadingEngines

def sepMat(object):

shadingGroups=getSGsFromShape(object)
ParentName=(object + "_lightMap_Group")
cmds.group(empty=1, n=ParentName)
i=0
while 1:
	if not ( i<len(shadingGroups) ):
		break
	
	theMaterial=cmds.listConnections(shadingGroups[i], s=True, d=False)
	clone=(object + "_" + theMaterial[0])
	cmds.duplicate(object, n=clone)
	cmds.parent(clone, ParentName)
	material=cmds.listConnections(shadingGroups[i], s=True, d=False)
	cmds.select(clone)
	cmds.ConvertSelectionToFaces()
	tempset=str(cmds.sets())
	tempgrps=cmds.listConnections(material[0], type='shadingEngine')
	cmds.select(cmds.sets(tempgrps[0], int=tempset))
	cmds.InvertSelection()
	cmds.delete()
	
	i=i + 1
	
cmds.delete(object)

selection=cmds.ls(sl=1)
sepMat(selection[0])

@wodong526
Copy link

Thank you very much! I just need this.

@wodong526
Copy link

Sorry, when I read your script, I found a command is cmds.ConvertSelectionToFaces. I didn't find this command when looking up the Maya documentation. Where can I find it? I would appreciate it if you could answer.

@GuyMicciche
Copy link

Sorry, when I read your script, I found a command is cmds.ConvertSelectionToFaces. I didn't find this command when looking up the Maya documentation. Where can I find it? I would appreciate it if you could answer.

I don't think this is a documented command. However you can see it is a runtime command in the PyMel documentation: https://download.autodesk.com/global/docs/maya2014/en_us/PyMel/generated/functions/pymel.core.runtime/pymel.core.runtime.ConvertSelectionToFaces.html

Mel equivalent ConvertSelectionToFaces; is undocumented, however when you check your Script Editor, you can see this command calls PolySelectConvert 1; which is located in PolySelectConvert.mel file inside your main Maya application. Infact, if you monitor your script editor, select an object, CONTROL + Right Click > To Faces >To Faces, and you convert to faces this way, the script editor calls ConvertSelectionToFaces; which just runs PolySelectConvert 1;

With Python, you can also do:

import pymel.core as pm
pm.mel.PolySelectConvert(1)

Same thing. I guess in Python,

from maya import cmds
cmds.ConvertSelectionToFaces()

Will just call the pymel command:

import pymel.core as pm
pm.mel.PolySelectConvert(1)

But you're right, it's not really documented.

@wodong526
Copy link

Thank you for your help. I have solved it perfectly.

@sitorender
Copy link

Thanks, very useful

@michalfratczak
Copy link

michalfratczak commented Apr 12, 2023

Thanks, I was looking for such a thing. I took the liberty to do some corrections and cleaning.
I cannot correctly paste code here, so this is the link: https://pastebin.com/5vhV2EeT

@MineClever
Copy link

MineClever commented Jul 31, 2023

# coding=utf-8
from maya import cmds

def getSGs(in_obj_name):
    # type: (str) -> list[str]
    if not cmds.objExists(in_obj_name): return []
    
    shadingEngines = set()  # type: set[str]
    ShapeNodes=cmds.listRelatives(in_obj_name, shapes=1, children=1) or []# type: list[str]
    if not ShapeNodes : return []
    
    for shape in ShapeNodes:
        dest=cmds.listConnections(shape, source=False, plugs=False, destination=True, type="shadingEngine") # type: list[str]
        if not dest : continue
        shadingEngines.update(dest)
        
    return list(shadingEngines)

def sepMat(objectName, suffixName = "_Splitted"):
    # type: (str, str) -> None
    
    shadingGroups=getSGs(objectName)
    if shadingGroups.__len__() <= 1: return

    nodeParentName = (objectName + suffixName) # type: str
    if not cmds.objExists(nodeParentName): 
        nodeParentName = cmds.group(empty=1, n=nodeParentName) # type: str
    
    for i in range(shadingGroups.__len__()):
        curMatSg=shadingGroups[i]
        
        cloneObjName = (objectName + "_" + curMatSg) # type: str
        cloneObjName = cmds.duplicate(objectName, n=cloneObjName)[0] # type: str
        cloneObjName = cmds.parent(cloneObjName, nodeParentName)[0] # type: str
        
        polyFacesSet = cmds.sets(cloneObjName + '.f[0:]') # type: str
        sgFacesSet = cmds.sets(cmds.sets(curMatSg, un=polyFacesSet)) # type: str
        cmds.delete(cmds.sets(polyFacesSet , subtract=sgFacesSet), polyFacesSet, sgFacesSet)
    else: cmds.delete(objectName)


def runScript(*args, **kw):
    
    selection = cmds.ls(sl=True, objectsOnly=True, noIntermediate=True)
    for sel in selection:
        try: sepMat(sel)
        except : continue
        
    cmds.select(cl=True)

if __name__ == "__main__":
    runScript()

More fast && clean

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