#Pass through the mesh's shape and return a texture name. import pymel as pm def getTextureFile(geo): sg = [] #Get the shading group from the selected mesh raw_sg = pm.listConnections(geo, type='shadingEngine') #Rapidly check for duplicates in the list- I do this by checking each item #against an empty list. #If the item is not in the empty list I append it. for element in raw_sg: if element not in sg: sg.append(element) #Get some info sgInfo = pm.listConnections(sg[0], type='materialInfo') fileNode = pm.listConnections(sgInfo[0], type='file') textureFile = pm.getAttr(fileNode[0].fileTextureName) print 'This is the file', str(textureFile) return str(textureFile)It still leaves a lot to be desired, for instance it doesn't know what to do if a mesh doesn't actually have a texture! But, provided it does, using the win32com module I can then send the texture file information onto Photoshop and Alienbrain and open files/check out texture chains etc etc.
EDIT:
------------------------------------------------------------------------------------------------------------
Thanks to Daydreamer who pointed out the missing pymel reference at the top of the snippet, as well as other issues with the script which I am working through...
After a happy weekend of actually reading part of the official tutorial, I have a slightly better understanding of how to access a mesh's attributes and nodes using PyMel. Here is a snippet of the above snippet that does pretty much the same thing, only using the pymel connections, input and output commands. The intention is only to test the functionality.
import pymel as pm geo = pm.ls(sl=True)[0].getShape() #Get the shading group from the selected mesh sg = geo.outputs(type='shadingEngine') #Work through the node to get the file texture name sgInfo = sg[0].connections(type='materialInfo') #It falls apart here if you have no file node! Oops... fileNode = sgInfo[0].connections(type='file') #Get the file texture name attribute's value textureFile = pm.getAttr(fileNode[0].fileTextureName) print 'This is the file', str(textureFile)
Hi Pete,
ReplyDeletenice.....
but, u can improve this snippet many folds.
eg.
In section
A. # Clean up the list(which looks misleading)
1. use list comprehension instead of normal loop. it will run faster then normal loop and u dont have to declare sg variable in advance.
2.it seems u r creating a new list named sg frm raw_sg, u can du thz by using deepcopy function or usin slicing.
B. #Pass through the mesh's shape and return a texture name. and #Get some info
1. Where is PyMel??
just using "pm" doesn't mean PyMel, don't u think if i use "cmds"(python in maya) instead of "pm" it will be exactly the same. where is OOP?
C. This code will also starts failing if my variables values are None. In simple, if i don't have texture over my selected mesh.
You need to add checks or validations.
Need more elaborate discussion, write in to me.
Or drop comment on my site.
Regards
Day Dreamer
www.daydreamer3d.weebly.com
Hi Day Dreamer, thanks for your comment! I've not used list comprehension before, I will have to look into it! My intention with that section of code is to remove any duplicate items. It's a bit of a dirty way of doing it, so if list comprehension is faster + cleaner I'm all for it!
DeleteB.1 - Bad copy paste on my part, I use "import pymel as pm" as my pymel reference and it was missing from the start of the snippet, fixed now! Thanks for pointing it out!
You are correct that the script totally falls flat if there are no textures assigned to a given mesh, which is a *major* flaw. Some checks would be the logical next step.
In the #Get some info, I must admit I'm pretty (extremely) new at Pymel- is this the way you would normally query for a texture file, or is there a simpler/more direct way?
# Note:- ____ means whitespaces
ReplyDeleteimport pymel as pm
# Check selection
sel = pm.ls(sl=True)
if not sel:
____print 'Selection is empty. Kindly select a geometry.'
____# if under function return here
# Assuming you are interested in single selected object
# (generally, i prefer last selected object, Maya Way)
# re-defying "sel" variable with just last object
sel = sel[-1]
geo = sel.getShape()
# Checking selected object is a mesh(shape)
if not geo:
____print 'No Shape Found For %s' % sel
____# if under function return here
#Get the shading group from the selected mesh
sg = geo.outputs(type='shadingEngine')
if not sg:
____print 'No Shading Engine Exists For %s' % geo
____# return here
#Work through the node to get the file texture name
sgInfo = sg[0].connections(type='materialInfo')
#It falls apart here if you have no file node! Oops...
fileNode = sgInfo[0].connections(type='file')
if not fileNode:
____print 'No Texture Exists For %s' % geo
____# return here
#Get the file texture name attribute's value
#textureFile = pm.getAttr(fileNode[0].fileTextureName)
textureFile = fileNode[0].fileTextureName.get()
if not textureFile:
____print 'No Texture Path Found For:-\n\t\tShape:- {0}\n\t\tTexture:- {1}'.format(geo, fileNode[0])
____return here
print 'This is the file %s' % textureFile
Why not remove duplicates in your list by simply doing a my_list = list(set(my_list))
ReplyDelete-Sven