Assign texture from file selection tool debug help needed(python)


#1

This is a section of a tool that is being implemented into my pipeline toolset. You select a folder with a bunch of images, select the one you wish to use from a dropdown menu, then select your object and hit apply. My issue is that I cannot do this to multiple objects in a scene, it only changes the material on the first object that is selected. The new shader that is created is also completely broken. The goal is to be able to select any object in the scene and apply a texture from the selected list to any of the objects. Help would be greatly appreciated.

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 Folder With Pictures”, 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.')
    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('%s.shaderNode'+'%s.outColor','textureMaterialGroup'+'%s.surfaceShader', force=True)
    cmds.connectAttr('fileTexture'+'%s.outColor','shaderNode'+'%s.color', force=True)
    cmds.surfaceShaderList('shaderNode', add='imageMaterialGroup')
    cmds.sets(object, e=True, forceElement='imageMaterialGroup')

TextureImport()


#2

You should use the tags for code so we could try your code.

I haven’t tried your code but I find some peculiar parts;

%s.shaderNode’+’%s.outColor’
You are using a %s string syntax without specifying the contents in a tuple.

cmds.connectAttr(’%s.shaderNode’+’%s.outColor’,‘textureMaterialGroup’+’%s.surfaceShader’, force=True)
I really don’t know what are you trying to do here, but I guess you want to connect your texture node with the shader. That would be something like this:

cmds.connectAttr(fileNode+’.outColor’, shaderNode+’.color’, force=True)

setAttr(‘fileTexture’ + ‘fileTextureName’…) without a dot before fileTextureName.
This should give you an error right away.

You are using names instead of variables so you could get errors if a file node called fileTexture already exists.

object = cmds.ls(sl=True)
cmds.ls will always give you a list, not a string.

I’d suggest to not mix singular and plural words. For example in your myFiles iteration you are using the word “items” (plural) for each item (singular), and using object (singular) for the selected list (plural).