getting defaultArnoldRenderOptions attributes - maya

I'm trying to write plugin for Maya using pymel. There is a little problem with using default attributes of Arnold renderer (outputfile format).
Code:
import maya.cmds as cmds
cmds.getAttr('defaultRenderGlobals.imageFormat') #return id of used format, for example png - 32
cmds.getAttr('defaultRenderGlobals.imageFormat') #return constant id=51 if Arnold Renderer set as current renderer
cmds.getAttr('defaultArnoldRenderOptions.?????') #how do the same with arnold options?

The code you have above is not PyMEL. I'll answer with PyMEL since it's what you asked for, and it's better than maya.cmds.
To get a list of all available attributes on a node, use listAttr. There are many attributes on defaultArnoldRenderOptions, and they are returned unsorted, so you may want to sort or filter the list to make it easier to find.
import pymel.core as pm
# all attributes
print pm.listAttr("defaultArnoldRenderOptions")
# print names of attributes sorted, one per line.
print ("\n").join(sorted(pm.listAttr("defaultArnoldRenderOptions")))
#result
...
ignoreSubdivision
ignoreTextures
ignore_list
imageFormat
indirectSampleClamp
indirectSpecularBlur
...
There's no outputfileformat, only imageFormat
Get and print the value of the imageFormat attribute
print pm.PyNode("defaultArnoldRenderOptions").attr("imageFormat").get()
#result
None

Related

Chef - Ruby - How to extract values from a nested array/list

I'm using this json content (I'm open to suggestions on better formatting here):
{"forwardingZones": [{"name": "corp.mycompany.com","dnsServers": ["192.168.0.1","192.168.0.2"]}]}
Note: we may add more items to this list as we scale out, both more IPs and more names, hence the "join(',')" in the end of the code below.
And I'm trying to loop through it to get this result:
corp.mycompany.com=192.168.0.1;192.168.0.2
Using this code:
forward_zones = node['DNS']['forward_zones'].each do |forwarded_zone|
forwarded_zone_name = forwarded_zone['name']
forwarded_zone_dns_servers = forwarded_zone['dns_servers'].join(';')
"#{forwarded_zone_name}=#{forwarded_zone_dns_servers}"
end.join(',')
This is the result that I get:
{"dnsServers"=>["192.168.0.1", "192.168.0.2"], "name"=>"corp.mycompany.com"}
What am i doing wrong...?
x.each returns x. You want x.map.

How to connect attributes from list when Maya does not find those attributes?

What I am looking to do is batch connect attributes from object A to object B. Just the transform attributes, so, I did this:
import maya.cmds as mc
sel = mc.ls(sl=True)
mc.connectAttr(sel[0]+'.t', sel[1]+'.t')
mc.connectAttr(sel[0]+'.r', sel[1]+'.r')
mc.connectAttr(sel[0]+'.s', sel[1]+'.s')
And then I thought it would be more clever if I created a list containing (translate, rotate and scale) and just iterate over that list instead of specifying ".t", ".r" and ".s".
So I did this:
import maya.cmds as mc
sel = mc.ls(sl=True)
attributes = ['.t', '.r', '.s']
for attr in attributes :
mc.connectAttr(sel[0].attr, sel[1].attr)
...to which the console says
# Error: AttributeError: file <maya console> line 7: 'unicode' object has no attribute 'attr' #
I did some searching, but it didn’t help me understand. Can someone explain why this is happening, and how I can achieve the desired results?
Your last line has to be:
mc.connectAttr(sel[0]+attr, sel[1]+attr)
You are using . as if it were the string concatenation error in Python, while + is.
Instead . is the attribute operator, which explains your error¹. When Python tries to interpret sel[0].attr, it first notes that sel[0] is a unicode object and then tries to get the attribute attr from that object. This attribute has nothing to do with the attr from your loop and in particular doesn’t exist. Hence the error message you got.
¹ Every object in Python has some attributes, which you can access with that syntax and which depend on the type object. To get familiar with this try:
a = 42
print(a.numerator)
print(a.denominator)
print(a.wrzlprmft)
# Raises AttributeError. This is what happened to you.
print(denominator)
# Raises NameError.
# This demonstrates that denominator is only defined as an attribute of a.

removing portion of filename

I have done some searching but cannot see how to actually code this. I am new to Python and not really sure what method I should use to try to do this.
I have some files that I would like to rename. Unfortunately the portion towards the file extension is never the same and would like to just remove it.
File name is like AC_DC - Shot Down In Flames (Official Video)-UKwVvSleM6w.mp3
Any help would be appreciated.
Since this looks like the result from youtube-dl, the "random" substring is most likely the unique video id, which in my experience is always 11 characters long. It can, however, include dashes (-), so the regex-approach suggested by smitrp would not always work.
I use this "dirty" workaround:
>>> original_name="AC_DC - Shot Down In Flames (Official Video)-UKwVvSleM6w.mp3"
>>> new_name=original_name[:-16]+".mp3"
>>> new_name
'AC_DC - Shot Down In Flames (Official Video).mp3'
Edit:
If you really, REALLY want to find the "-XXXX"-portion, have a look at str.rfind(). This will help you to find the index of the last dash (-), which you can directly use for the slice notation of the string.
Disclaimer:
This will provide wrong results, if the video id contains a dash, e.g. here: https://www.youtube.com/watch?v=7WVBEB8-wa0
Then you will find the last dash, remove -wa0 and be left with -7WVBEB8 at the end of the filename.
Using idea of the above answer, one can also take into account that a normal word does not
contain more than one capital character.
def youtube_name_fix(folder):
import os
from pathlib import Path
import re
REGEX = re.compile(r'[A-Z]')
for name in os.listdir(folder):
basename = Path(name)
last_12 = basename.stem[-12:]
# check if the end string is not all uppercase (then it could be part of a valid name)
if not last_12.isupper():
# check if the last string has more than one uppercase letters
if len(REGEX.findall(last_12)) > 1:
# remove the end youtube string and create new full path
new_name = os.path.join(folder, basename.stem[:-12] + basename.suffix)
try:
os.rename(os.path.join(folder,name), new_name)
except Exception as e:
print(e)
> youtube_name_fix(p)
old name -> "4-Discrete and Continuous Probability Models-esHwigpYggU.mp4"
new name -> "4-Discrete and Continuous Probability Models.mp4"

Select random item from an array with certain probabilities and add it to the stage

Its quite a big task but ill try to explain.
I have an array with a list of 200 strings and I want to be able to randomly select one and add it to the stage using code. I have movieclips exported for actionscript with the same class name as the strings in the array. Also, if it is possible, would I be able to select the strings with predictability such as the first has a 0.7 chance the second a 0.1 etc. Here is what i have currently
var nameList:Array=["Jimmy","Bob","Fred"]
var instance:DisplayObject = createRandom(nameList);
addChild(instance);
function createRandom(typeArray:Array):*
{
// Select random String from typeArray.
var selection:String = typeArray[ int(Math.random() * typeArray.length) ];
// Create instance of relevant class.
var Type:Class = getDefinitionByName(selection) as Class;
// Return created instance.
return new Type();
}
All this throws me this error
ReferenceError: Error #1065: Variable [class Jimmy] is not defined.
Ive searched for other threads similar but none combine the three specific tasks of randomisation, predictability and addChild().
I think that you've got two problems: a language problem and a logic problem. In the .fla connected to your code above, in the Library find each symbol representing a name and write into the 'AS linkage' column for that symbol the associated name -- e.g., 'Bob,' 'Fred' -- just the name, no punctuation.
Now getDefinitionByName() will find your 'Class'
If you put a different graphic into each MovieClip -- say, a piece of fruit or a picture of Bob,Jim, Fred -- and run your program you'll get a random something on stage each time.
That should solve your language problem. But the logic problem is a little harder, no?
That's why I pointed you to Mr. Kelly's solution (the first one, which for me is easier to grasp).

Using PyMEL to set the "Alpha to Use" attribute in an object of class psdFileTex

I am using Maya to do some procedural work, and I have a lot of textures that I need to load into Maya, and they all have transparencies (alpha channels). I would very much like to be able to automate this process. Using PyMEL, I can create my textures and hook them up to a shader, but the alpha doesn't set properly by default. There is an attribute in the psdFileTex node called "Alpha to Use", and it must be set to "Transparency" in order for my alpha channel to work. My question is this - how do I use PyMEL scripting to set the "Alpha to Use" attribute properly?
Here is the code I am using to set up my textures:
import pymel.core as pm
pm.shadingNode('lambert', asShader=True, name='myShader1')
pm.sets(renderable=True, noSurfaceShader=True, empty=True, name='myShader1SG')
pm.connectAttr('myShader1.outColor', 'myShader1SG.surfaceShader', f=True)
pm.shadingNode('psdFileTex', asTexture=True, name='myShader1PSD')
pm.connectAttr('myShader1PSD.outColor', 'myShader1.color')
pm.connectAttr('myShader1PSD.outTransparency', 'myShader1.transparency')
pm.setAttr('myShader1ColorPSD.fileTextureName', '<pathway>/myShader1_texture.psd', type='string')
If anyone can help me, I would really appreciate it.
Thanks
With any node, you can use listAttr() to get the available editable attributes. Run listAttr('myShaderPSD'), note in it's output, there will be two attributes called 'alpha' and 'alphaList'. Alpha, will return you the current selected alpha channel. AlphaList will return you however many alpha channels you have in your psd.
Example
pm.PyNode('myShader1PSD').alphaList.get()
# Result: [u'Alpha 1', u'Alpha 2'] #
If you know you'll only ever be using just the one alpha, or the first alpha channel, you can simply do this.
psdShader = pm.PyNode('myShader1PSD')
alphaList = psdShader.alphaList.get()
if (len(alphaList) > 0):
psdShader.alpha.set(alphaList[0])
else:
// No alpha channel
pass
Remember that lists start iterating from 0, so our first alpha channel will be located at position 0.
Additionally and unrelated, while you're still using derivative commands of the maya.core converted for Pymel, there's still some commands you can use to help make your code read nicer.
pm.setAttr('myShader1ColorPSD.fileTextureName', '<pathway>/myShader1_texture.psd', type='string')
We can convert this to pymel like so:
pm.PyNode('myShader1ColorPSD').fileTextureName.set('<pathway>/myShader1_texture.psd')
And:
pm.connectAttr('myShader1PSD.outColor', 'myShader1.color')
Can be converted to:
pm.connect('myShader1PSD.outColor', 'myShader1.color')
While they may only be small changes, it reads just the little bit nicer, and it's native PyMel.
Anyway, I hope I have helped you!

Resources