从文件选择创建着色器并应用于所选对象
Create shader from file selection and apply to selected object
您 select 一个包含一堆图像的文件夹,select 您希望从下拉菜单中使用的图像,然后 select 您的对象并点击应用。我的问题是我无法对场景中的多个对象执行此操作,它只会更改 selected 的第一个对象上的 material。当我尝试对场景中的另一个对象执行此操作时,它只会替换第一个对象上的图像,而不会创建另一个着色器。目标是能够 select 场景中的任何对象并将 selected 列表中的纹理应用于场景中的任何对象。帮助将不胜感激。我在下面提供了工具。
import maya.cmds as cmds
from os import listdir
class TextureImport():
def __init__(self):
if cmds.window(TextureImport, q=True, exists=True):
cmds.deleteUI(TextureImport)
GUI=cmds.window(title="Texture Import Tool", widthHeight=(250,160), s=True, tlb=True)
cmds.rowColumnLayout(numberOfColumns=1, columnAlign=(1, 'center'), columnAttach=(1, 'both', 0), cw=(1,250))
cmds.button(label="Select Directory", command=self.select_dir)
cmds.separator(style='in', h=20)
cmds.optionMenu('optionMenu', label="File List")
cmds.button(label="Clear List", command=self.clear_list)
cmds.separator(style='in', h=20)
cmds.text('Select your object, then:', h=25)
cmds.button(label="Apply Texture", command=self.apply_texture)
cmds.setParent('..')
cmds.showWindow()
def select_dir(self, *args):
basicFilter = "Image Files (*.jpg *.jpeg *.tga *.png *.tiff *.bmp *.psd)"
self.myDir = cmds.fileDialog2 (fileFilter=basicFilter, dialogStyle=2, fm=3)
myFiles = listdir(self.myDir[0])
for items in myFiles:
fileEndings = ('.psd','.PSD','.jpg','JPG','.jpeg','.JPEG','.tga','.TGA','.png','.PNG','.tiff','.TIFF','.bmp','.BMP')
if items.endswith(fileEndings):
cmds.menuItem(items)
else:
cmds.warning(items + 'This is not a valid image type, you fool.')
print myFiles
def clear_list(self, *args):
fileList = cmds.optionMenu('optionMenu', q=True, itemListLong=True)
if fileList:
cmds.deleteUI(fileList)
def apply_texture(self, *args):
object = cmds.ls(sl=True)
selectedMenuItem = cmds.optionMenu('optionMenu', q=True, value=True)
cmds.sets(name='imageMaterialGroup', renderable=True, empty=True)
shaderNode = cmds.shadingNode('phong', name='shaderNode', asShader=True)
fileNode = cmds.shadingNode('file', name='fileTexture', asTexture=True)
cmds.setAttr('fileTexture'+'.fileTextureName', self.myDir[0]+'/'+selectedMenuItem, type="string")
shadingGroup = cmds.sets(name='textureMaterialGroup', renderable=True, empty=True)
cmds.connectAttr('shaderNode'+'.outColor','textureMaterialGroup'+'.surfaceShader', force=True)
cmds.connectAttr('fileTexture'+'.outColor','shaderNode'+'.color', force=True)
cmds.surfaceShaderList('shaderNode', add='imageMaterialGroup')
cmds.sets(object, e=True, forceElement='imageMaterialGroup')
TextureImport()
目标是能够 select 场景中的任何对象并将 selected 列表中的纹理应用于任何对象。例如,艺术家可以设置多个平面来应用参考图像。该工具将从 selected 文件创建着色器,这将使他们的工作变得非常容易。对此提供帮助将不胜感激。
您的问题在于您尝试连接属性的方式:
fileNode = cmds.shadingNode('file', name='fileTexture', asTexture=True)
cmds.setAttr('fileTexture'+'.fileTextureName', ..., type="string")
您使用文件节点的显式名称:'fileTexture'。结果是如果节点存在,则使用现有节点而不是新创建的节点。您必须以这种方式使用 fileNode 变量构建属性:
fileNode = cmds.shadingNode('file', name='fileTexture', asTexture=True)
cmds.setAttr(fileNode+'.fileTextureName', ..., type="string")
在其他 connectAttr() 函数中也应进行相同的更改。
您 select 一个包含一堆图像的文件夹,select 您希望从下拉菜单中使用的图像,然后 select 您的对象并点击应用。我的问题是我无法对场景中的多个对象执行此操作,它只会更改 selected 的第一个对象上的 material。当我尝试对场景中的另一个对象执行此操作时,它只会替换第一个对象上的图像,而不会创建另一个着色器。目标是能够 select 场景中的任何对象并将 selected 列表中的纹理应用于场景中的任何对象。帮助将不胜感激。我在下面提供了工具。
import maya.cmds as cmds
from os import listdir
class TextureImport():
def __init__(self):
if cmds.window(TextureImport, q=True, exists=True):
cmds.deleteUI(TextureImport)
GUI=cmds.window(title="Texture Import Tool", widthHeight=(250,160), s=True, tlb=True)
cmds.rowColumnLayout(numberOfColumns=1, columnAlign=(1, 'center'), columnAttach=(1, 'both', 0), cw=(1,250))
cmds.button(label="Select Directory", command=self.select_dir)
cmds.separator(style='in', h=20)
cmds.optionMenu('optionMenu', label="File List")
cmds.button(label="Clear List", command=self.clear_list)
cmds.separator(style='in', h=20)
cmds.text('Select your object, then:', h=25)
cmds.button(label="Apply Texture", command=self.apply_texture)
cmds.setParent('..')
cmds.showWindow()
def select_dir(self, *args):
basicFilter = "Image Files (*.jpg *.jpeg *.tga *.png *.tiff *.bmp *.psd)"
self.myDir = cmds.fileDialog2 (fileFilter=basicFilter, dialogStyle=2, fm=3)
myFiles = listdir(self.myDir[0])
for items in myFiles:
fileEndings = ('.psd','.PSD','.jpg','JPG','.jpeg','.JPEG','.tga','.TGA','.png','.PNG','.tiff','.TIFF','.bmp','.BMP')
if items.endswith(fileEndings):
cmds.menuItem(items)
else:
cmds.warning(items + 'This is not a valid image type, you fool.')
print myFiles
def clear_list(self, *args):
fileList = cmds.optionMenu('optionMenu', q=True, itemListLong=True)
if fileList:
cmds.deleteUI(fileList)
def apply_texture(self, *args):
object = cmds.ls(sl=True)
selectedMenuItem = cmds.optionMenu('optionMenu', q=True, value=True)
cmds.sets(name='imageMaterialGroup', renderable=True, empty=True)
shaderNode = cmds.shadingNode('phong', name='shaderNode', asShader=True)
fileNode = cmds.shadingNode('file', name='fileTexture', asTexture=True)
cmds.setAttr('fileTexture'+'.fileTextureName', self.myDir[0]+'/'+selectedMenuItem, type="string")
shadingGroup = cmds.sets(name='textureMaterialGroup', renderable=True, empty=True)
cmds.connectAttr('shaderNode'+'.outColor','textureMaterialGroup'+'.surfaceShader', force=True)
cmds.connectAttr('fileTexture'+'.outColor','shaderNode'+'.color', force=True)
cmds.surfaceShaderList('shaderNode', add='imageMaterialGroup')
cmds.sets(object, e=True, forceElement='imageMaterialGroup')
TextureImport()
目标是能够 select 场景中的任何对象并将 selected 列表中的纹理应用于任何对象。例如,艺术家可以设置多个平面来应用参考图像。该工具将从 selected 文件创建着色器,这将使他们的工作变得非常容易。对此提供帮助将不胜感激。
您的问题在于您尝试连接属性的方式:
fileNode = cmds.shadingNode('file', name='fileTexture', asTexture=True)
cmds.setAttr('fileTexture'+'.fileTextureName', ..., type="string")
您使用文件节点的显式名称:'fileTexture'。结果是如果节点存在,则使用现有节点而不是新创建的节点。您必须以这种方式使用 fileNode 变量构建属性:
fileNode = cmds.shadingNode('file', name='fileTexture', asTexture=True)
cmds.setAttr(fileNode+'.fileTextureName', ..., type="string")
在其他 connectAttr() 函数中也应进行相同的更改。