0

My goal is to set a shader to each parts of a geo. The parts of the geo are typically a group of attached faces. I do this to bake an ID map and then use it in Substance Painter.

So far, I separate the parts, then assign a shader to each and unite them back. I eventually delete the history to clean the outliner and the mesh itself.

import maya.cmds as mc
import random

selection = mc.ls(sl=True)[0]
parent = mc.listRelatives( selection, ap = True)[0]
mc.polySeparate(selection)
parts = mc.ls(sl=True)

for p in parts:
    sha = mc.shadingNode('lambert', asShader=True, name=p+"_lambert")
    sg = mc.sets(empty=True, renderable=True, noSurfaceShader=True,  name=p+"_SG")
    mc.setAttr(sha+".color", random.uniform(0.0, 1.0), random.uniform(0.0, 1.0), random.uniform(0.0, 1.0))
    mc.connectAttr( sha+".outColor", sg+".surfaceShader", f=True)
    mc.sets(p, e=True, forceElement=sg)

result = mc.select( selection, r = True )
sel = mc.ls( sl=True )
parts = mc.listRelatives( sel[0], c = True )
mc.polyUnite(parts, muv = True, name = selection)
mc.DeleteHistory()

I've got my shaders on parts but lose my original group under which the mesh was parented, and it doesn't feel right to do it this way.

Is there a way to create sets of parts without using 'separate' and assign a shader to each set?

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
KL75
  • 3
  • 1

1 Answers1

0

I am assuming that you are assigning shaders on a combined object but my script should give you the idea : (run it and it will assign random shader on the combined sphere)

Just to resume Im listing the faces of the object selected. I take one face, grow the selection until it cant anymore Assign a shader on them, removing the selection of faces from the main list and do it again in a loop at the end im producing some kind of history by creating a set per object and sub set per lambert assigned

import maya.cmds as cmds
import random

def growComponent(component):
    # component = vertices[0]
    check = component.split('.')
    if len(check) != 2:
        cmds.error('please select one component in order to grow the selection')

    mySel = [component]
    counterSel = len(cmds.ls(component, fl = True))
    myFinalSel = 0

    while myFinalSel != counterSel:
        mySel = component
        counterSel = len(mySel)
        vert = cmds.polyListComponentConversion(mySel, tv = True)
        component = cmds.polyListComponentConversion(vert, tf = True)
        component = cmds.ls(component, fl = True)
        myFinalSel = len(component)

    component = cmds.polyListComponentConversion(component, tv = True)
    return component

# =========================
#just to illustrate an exemple selection of 10 sphere combined
psph = [cmds.polySphere()[0] for i in range(10)]
for i in psph:
    cmds.setAttr(i+'.t', random.uniform(0.0, 3.0), random.uniform(0.0, 3.0), random.uniform(0.0, 3.0))
sph_comb = cmds.polyUnite(psph)
cmds.delete(sph_comb, ch=True)
# ===============================


selection = cmds.ls(sph_comb)[0]

faceSet = cmds.sets(em = True, name = '{}_sg_faceset'.format(selection))

combinedFaceGrp = cmds.ls(selection + '.f[:]', fl = True)

partsFace = []
x = 0
while combinedFaceGrp or x>10000:

    len(combinedFaceGrp)
    component = growComponent(combinedFaceGrp[0])
    faces = cmds.polyListComponentConversion(component, tf = True)
    partset = cmds.sets(faces, name='part{}_{}_set'.format(x, selection))
    cmds.sets(partset, edit = True, fe = faceSet)
    x+=1

    # remove face selected
    faces_fl = cmds.ls(faces, fl=True)
    combinedFaceGrp = list(set(combinedFaceGrp)-set(faces_fl))

    # assign shader
    sha = cmds.shadingNode('lambert', asShader=True, name="{}_{}_lambert".format(selection, x))
    sg = cmds.sets(empty=True, renderable=True, noSurfaceShader=True,  name="{}_{}_sg".format(selection, x))
    cmds.setAttr(sha+".color", random.uniform(0.0, 1.0), random.uniform(0.0, 1.0), random.uniform(0.0, 1.0))
    cmds.connectAttr( sha+".outColor", sg+".surfaceShader", f=True)
    cmds.sets(faces, e=True, forceElement=sg)
DrWeeny
  • 2,487
  • 1
  • 14
  • 17