如何高效且非破坏性地对地理区域执行着色器分配?
How can I perform shader assignment to a geo efficiently and non-destructively?
我的目标是为地理区域的每个部分设置一个着色器。 geo 的部分通常是一组附加的面。我这样做是为了烘焙 ID 贴图,然后在 Substance Painter 中使用它。
到目前为止,我将各个部分分开,然后为每个部分分配一个着色器并将它们重新组合起来。我最终删除了历史记录以清理大纲和网格本身。
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()
我已经在零件上设置了我的着色器,但丢失了我的原始组,网格在该组下是父级的,这样做感觉不对。
有没有办法在不使用 'separate' 的情况下创建多组零件并为每组分配一个着色器?
我假设您在组合对象上分配着色器,但我的脚本应该给您想法:(运行 它会在组合球体上分配随机着色器)
只是为了恢复我列出所选对象的面孔。
我拿一张脸,增加选择直到它不能再
为它们分配一个着色器,从主列表中删除选择的面
然后再循环一次
最后,我通过为每个对象创建一个集合和为每个分配的兰伯特
创建子集来生成某种历史记录
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)
我的目标是为地理区域的每个部分设置一个着色器。 geo 的部分通常是一组附加的面。我这样做是为了烘焙 ID 贴图,然后在 Substance Painter 中使用它。
到目前为止,我将各个部分分开,然后为每个部分分配一个着色器并将它们重新组合起来。我最终删除了历史记录以清理大纲和网格本身。
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()
我已经在零件上设置了我的着色器,但丢失了我的原始组,网格在该组下是父级的,这样做感觉不对。
有没有办法在不使用 'separate' 的情况下创建多组零件并为每组分配一个着色器?
我假设您在组合对象上分配着色器,但我的脚本应该给您想法:(运行 它会在组合球体上分配随机着色器)
只是为了恢复我列出所选对象的面孔。 我拿一张脸,增加选择直到它不能再 为它们分配一个着色器,从主列表中删除选择的面 然后再循环一次 最后,我通过为每个对象创建一个集合和为每个分配的兰伯特
创建子集来生成某种历史记录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)