Hey guys,
Sorry- I'm aware this has been asked a hundred times over, but I'm struggling to find a way to get materials from a mesh fast and it doesn't help that I'm very new to pymel. I'm trying to get the materials of a mesh by face order because that is how I believe the material names are stored in an fbx when the fbx is written- but I can't find a way to do it quickly.
This is the best I've got:
def get_materials_by_face_count_selection(transform):
allFaces= len(transform.f)
materials = []
for face in range(allFaces):
thisFace = transform + ".f[" + str(face) + "]"
mc.select(thisFace)
mc.hyperShade(shaderNetworksSelectMaterialNodes=True)
material = ''.join(mc.ls(selection=True))
#print ("material: " + material)
if material not in materials:
materials.append(str(material))
return materials
This takes 12 seconds to run on a mesh with 16k verts/faces and over a minute for something with 66k verts ... which makes sense, I'm asking Maya to run select material on this face 66000 times. But I can't think of a better way to do this.
The reason I'm doing this is because I'm trying to setup an export pipeline in our studio for Maya to Unity. You hit export from a custom menu in Maya, Maya studies the mesh and writes the materials (in order) to an XML, this mesh then gets exported to a location in Unity. The Unity Asset Post processor picks up the fbx, studies the xml and automatically assigns materials and then saves this as prefab variant next to the fbx. This is how it has worked for years in 3ds Max currently and I can't get this to work as well in Maya because the get materials part takes ages to run.
Thoughts? Suggestions? Ideas?
EDIT: I also have this, which runs fast- but doesn't get the materials by face order and therefore doesn't work with the pipeline correctly:
def get_materials_on_selected_meshes(mesh):
all_materials = list()
for shading_engine in mesh.getShape().listConnections(type='shadingEngine'):
materials = pm.listConnections('%s.surfaceShader' %shading_engine)
if materials is not None and len(materials) > 0:
all_materials.extend(materials)
# Swap to a set to force a single instance, then back to a list
all_materials = list(set(all_materials))
return all_materials
Replies
Something easy to do is gather all the material assignments and sort them by lowest face index. In this case, I took a 50k sphere with 3 materials assigned to it.
initialShadingGroup