Proper way to use setAttr with channel box selection - python

please bear with me - I'm new to all this. I tried the searches and have only found bits and pieces to what I'm looking for, but not what I need to connect them.
Basically, I'm trying to create a Python script that allows the user to simply "0" out multiple selected attributes on Maya's Channel box.
So far I have:
import maya.cmds as cmds
selObjs = cmds.ls(sl=1)
selAttrs = cmds.channelBox("mainChannelBox", q=1, sma=1)
print selObjs # returns [u'pCube1']
print selAttrs # returns [u'ty']
If I would like to set the attributes:
cmds.setAttr(selObjs + "." + selAttrs, '0')
of course this is wrong, so how do I properly execute the setAttr command in this sceneario? (The intention includes having to set them if I have multiple selected attributes in the channel box).
I found that in MEL, it works like this. So really I just need help figuring out how to create the python counterpart of this:
string $object[] = `ls -sl`;
string $attribute[] = `channelBox -q -sma mainChannelBox`;
for ($item in $object)
for($attr in $attribute)
setAttr ($item + "." + $attr) 0;
Moving after that, I need an if loop where, if the attribute selected is a scale attribute, the value should be 1 - but this is something I'll look into later, but wouldn't mind being advised on.
Thanks!

So here's what I finally came up with:
import maya.cmds as cmds
selObjs = cmds.ls(sl=1)
selAttrs = cmds.channelBox("mainChannelBox", q=1, sma=1)
scales = ['sy','sx','sz','v']
if not selObjs:
print "no object and attribute is selected!"
elif not selAttrs:
print "no attribute is selected!"
else:
for eachObj in selObjs:
for eachAttr in selAttrs:
if any(scaleVizItem in eachAttr for scaleVizItem in scales):
cmds.setAttr (eachObj+"."+eachAttr, 1)
else:
cmds.setAttr (eachObj+"."+eachAttr, 0)
This will reset the basic transformations to their defaults. Including an if for the scale and visibility values.

I managed to come up with this:
import maya.cmds as cmds
selObjs = cmds.ls(sl=1)
selAttrs = cmds.channelBox("mainChannelBox", q=1, sma=1)
for each in selObjs:
for eachAttr in selAttrs:
cmds.setAttr (each+"."+eachAttr, 0)
And It's working to zero out selected attributes perfectly.
Now im at the stage of figuring out how to get the script to recognize if it contains scale attributes - to change that value to 1 instead of 0. (stuck at how to extract values from a list at the moment)

Related

I want to define (create) and use different variable (using suffix) through loop (specially for loop)

I want to create multiple variable through for loop to further use and compare in the program.
Here is the code -
for i in range(0,len(Header_list)):
(f'len_{i} = {len(Header_list[i]) + 2 }')
print(len_0);print(f'len{i}')
for company in Donar_list:
print(company[i],f"len_{i}")
if len(str(company[i])) > len((f"len_{i}")) :
(f'len_{i}') = len(str(company[i]))
print(f"len_{i}")
But what is happening, though I managed to create variable len_0,len_1,len_2... in line-2, in line - 3 I also can print len_0..etc variable by only using print(len_0), but I can't print it the values of these by - print(f'len_{i}')
In line 5 I also can't compare with the cofition with my intension. I want it do create variable and compare it further when as it necessary, in this case under for loop.What should I do now? I am a beginner and I can do it using if statement but that wouldn't be efficient, also my intention is not to create any **data structure ** for this.
I don't know whether I could manage to deliver you what I am trying to say. Whatever I just wanna create different variable using suffix and also comprare them through for loop in THIS scenario.
Instead of dynamically creating variables, I would HIGHLY recommend checking out dictionaries.
Dictionaries allow you to store variables with an associated key, as so:
variable_dict = dict()
for i in range(0,len(Header_list)):
variable_dict[f'len_{i}'] = {len(Header_list[i]) + 2 }
print(len_0)
print(f'len{i}')
for company in Donar_list:
print(company[i],f"len_{i}")
if len(str(company[i])) > len(variable_dict[f"len_{i}"]) :
variable_dict[f'len_{i}'] = len(str(company[i]))
print(f"len_{i}")
This allows you to access the values using the same key:
len_of_4 = variable_dict['len_4']
If you REALLY REALLY need to dynamically create variables, you could use the exec function to run strings as python code. It's important to note that the exec function is not safe in python, and could be used to run any potentially malicious code:
for i in range(0,len(Header_list)):
exec(f'len_{i} = {len(Header_list[i]) + 2 }')
print(len_0);print(f'len{i}')
for company in Donar_list:
print(company[i],f"len_{i}")
if exec(f"len(str(company[i])) > len(len_{i})"):
exec(f'len_{i} = len(str(company[i]))')
print(f"len_{i}")
In python everything is object so use current module as object and use it like this
import sys
module = sys.modules[__name__]
Header_list=[0,1,2,3,4]
len_ = len(Header_list)
for i in range(len_):
setattr(module, f"len_{i}", Header_list[i]+2)
print(len_0)
print(len_1)
Header_list=[0,1,2,3,4]
for i in range(0,5):
exec(f'len_{i} = {Header_list[i] + 2 }')
print(f'len{i}')
output:
len0
len1
len2
len3
len4

Colour Difference in The Foundry NUKE

So I am trying to make a painterly node group with Python code straight so I can use it for future projects but I can't seem to get the power part of the formula in nuke to work from this colour difference formula( I'm also new to Nuke so if there is a better way of writing this please let me know it would be awesome thank you, or if I'm doing this wrong completely also let me know)
The following formula for color difference is used to create the
difference image: |(r1,g1,b1) – (r2,g2,b2)| = ((r1 – r2)^2 + (g1
–g2)^2 + (b1 – b2)^2)^1/2.
nRedShuffle = nuke.nodes.Shuffle()
nRedShuffle['red'].setValue('red')
nRedShuffle['green'].setValue('red')
nRedShuffle['blue'].setValue('red')
nRedShuffle['alpha'].setValue('red')
nGreenShuffle = nuke.nodes.Shuffle()
nGreenShuffle['red'].setValue('green')
nGreenShuffle['green'].setValue('green')
nGreenShuffle['blue'].setValue('green')
nGreenShuffle['alpha'].setValue('green')
#...(so on for the rest of rgba1 and rgba2)
nGreenShuffle2 = nuke.nodes.Shuffle()
nGreenShuffle2['red'].setValue('green')
nGreenShuffle2['green'].setValue('green')
nGreenShuffle2['blue'].setValue('green')
nGreenShuffle2['alpha'].setValue('green')
nBlueShuffle2 = nuke.nodes.Shuffle()
nBlueShuffle2['red'].setValue('blue')
nBlueShuffle2['green'].setValue('blue')
nBlueShuffle2['blue'].setValue('blue')
nBlueShuffle2['alpha'].setValue('blue')
#I am having troubles with the powers below
redDiff = nuke.nodes.Merge2(operation='minus', inputs=[nRedShuffle2, nRedShuffle])
redDiffMuli = nuke.nodes.Merge2(operation='multiply', inputs=[redDiff, redDiff])
greenDiff = nuke.nodes.Merge2(operation='minus', inputs=[nGreenShuffle2, nGreenShuffle])
greenDiffMuli = nuke.nodes.Merge2(operation='multiply', inputs=[greenDiff, greenDiff])
blueDiff = nuke.nodes.Merge2(operation='minus', inputs=[nBlueShuffle2, nBlueShuffle])
blueDiffMuli = nuke.nodes.Merge2(operation='multiply', inputs=[blueDiff, blueDiff])
redGreenAdd = nuke.nodes.Merge2(operation='plus', inputs=[redDiffMuli, greenDiffMuli])
redGreenBlueAdd = nuke.nodes.Merge2(operation='plus', inputs=[redGreenAdd, blueDiffMuli])
Here are at least two ways to implement Color Difference formula for two images. You can use difference op in Merge node or you can write a formula in field for each channel inside MergeExpression node:
Expression for each channel is as simple as this:
abs(Ar-Br)
abs(Ag-Bg)
abs(Ab-Bb)
Python commands
You can use .nodes.MergeExpression methodology:
import nuke
merge = nuke.nodes.MergeExpression(expr0='abs(Ar-Br)',
expr1='abs(Ag-Bg)',
expr2='abs(Ab-Bb)')
or regular .createNode syntax:
merge = nuke.createNode('MergeExpression')
merge['expr0'].setValue('abs(Ar-Br)')
merge['expr1'].setValue('abs(Ag-Bg)')
merge['expr2'].setValue('abs(Ab-Bb)')
Full code version
import nuke
import nukescripts
red = nuke.createNode("Constant")
red['color'].setValue([1,0,0,1])
merge = nuke.createNode('MergeExpression')
merge['expr0'].setValue('abs(Ar-Br)')
merge['expr1'].setValue('abs(Ag-Bg)')
merge['expr2'].setValue('abs(Ab-Bb)')
yellow = nuke.createNode("Constant")
yellow['color'].setValue([1,1,0,1])
merge.connectInput(0, yellow)
nuke.toNode('MergeExpression1').setSelected(True)
nukescripts.connect_selected_to_viewer(0)
# Auto-alignment in Node Graph
for everyNode in nuke.allNodes():
everyNode.autoplace()
Consider! MergeExpression node is much slower that regular Merge(difference) node.

Maya – How to reorder Shelves alphabetically?

I'm trying to alphabetically order Maya shelves. I know that I can import shelves in order but I want to do this after the shelves are imported as the default Maya shelves are automatically imported into Maya.
I tried using the position argument in the shelfLayout command but I'm not sure if it's the right one or if it is, then I don't know how to use it. If someone could shed some light on this, it would be amazing.
Look at the following code snippet to find out how to reorder Shelf Tabs alphabetically:
import maya.cmds as cmds
import maya.mel as mel
def reorderTabsAlphabetically():
gshelf = mel.eval("$temp = $gShelfTopLevel")
shelves = cmds.tabLayout(gshelf, q=1, childArray=1)
total = len(shelves)
pref = 'abc'
print(total) # 16 tabs
shelf = sorted([s for s in shelves if s.startswith(pref)]) + # line break
sorted([s for s in shelves if not s.startswith(pref)])
for i, object in enumerate(shelf):
i += 1
sIndex = cmds.tabLayout(gshelf, q=1, childArray=1).index(object) + 1
cmds.tabLayout(gshelf, e=1, moveTab=(sIndex, i))
reorderTabsAlphabetically()
As you can see all the tabs are now arranged in the ascending order (alphabetically).

Setting render layer (Foreground, Character and Background in its own renderlayer) with Python

I've been stuck in figuring out how to split the environment into foreground and background. I've been thinking of getting the value of "distance from camera" (through "display > heads up display > object details") so I can use it to split into foreground and background using the value of distance character from camera as a guide.
The problem is that I don't know how to get it's value in python. So can someone help me please?
I'm using Maya 2016.
I got "none" in this command :
import maya.cmds as cmds
print cmds.headsUpDisplay('HUDObjDetDistFromCam', q=1)
Rather than trying to hijack object distance from camera, you can just calculate it yourself.
import math
import maya.cmds as cmds
def distance_to_camera(obj, cam):
cam_pos = cmds.xform(cam, t=True, ws=True, q=True)
object_pos = cmds.xform(obj, t=True, ws=True, q=True)
raw_dist = [a-b for a, b in zip(cam_pos, object_pos)]
return math.sqrt (sum([a**2 for a in raw_dist]))
distance_to_camera('pCube1', 'persp')
raw_dist = [a-b for a, b in zip(cam_pos, object_pos)] is taking two lists of 3 numbers (the positions) and subtracting each item in one list from it's opposite number in the other.
math.sqrt (sum([a**2 for a in raw_dist])) is the square root of the squares of the three numbers in raw_dist -- that is, the distance. You can do this using the Maya API but this version doesn't require any extra imports beside math

Python: How to return an instance of an object along with attributes assigned with setattr

I am still very new to python, but I need to interface with some software that is written as a bunch of python modules (.py files in case I incorrectly identified them as "modules.") This program has some very useful and complicated functions that I really cannot feasibly hack (if nothing else, because every time I update the software, I will have to re-hack everything.)
I have a python script that looks like this:
from software import thingfromsoftware
def mything(x,y,someboolean=True,etc)
var=thingfromsoftware(x,y)
#....code....
setattr(var, 'dimensions', somearraything)
return(var)
Then, if I try:
result=mything(4,5)
then result correctly contains the values of all the attributes first assigned to it via thingfromsoftware but result.dimensions has not been assigned (has no attribute "dimensions")
The goal is to store the dimensions of every result computed and configured by myfunctionthing in some semi-coherent manner.
Real code (upon request)
from ase.structure import nanotube
from ase import Atoms, view, io
from numpy import *
from Avogadro import Molecule, MoleculeFile
import cPickle as pickle
import os
def make_nanotube(n,m,length=1,TYPE='free'):
#This will set up leads so transport occures along the z axis and leads are aligned along the y axis (so they may be separated along the x axis.)
os.chdir("/tmp")
print 'Making ('+str(n)+','+str(m)+') nanotube with '+str(length)+" unit cell as "+str(TYPE)
tube = nanotube(n, m, length=length, bond=1.420, symbol='C')
center=tube.get_center_of_mass()
name='tube:('+str(n)+', '+str(m)+'):unit cells:'+str(length)+':'+str(TYPE)+'.xyz'
io.write(str(name), tube)
print 'Computing bonds'
mol = MoleculeFile.readMolecule(str(name))
RELOAD=0
for atom in mol.atoms[:]:
if len(atom.bonds)<2 and atom.pos[-1]<center[-1]:
print 'Relocating atom '+str(atom.index)+' from '+str(atom.pos[-1])+' to '+str(tube.get_cell()[-1, -1] + atom.pos[-1])
tube.positions[atom.index, -1] += tube.get_cell()[-1, -1]
RELOAD=1
print 'Orienting tube'
tip_atom=tube.get_positions()[:, -1].argmax() #the tip on the right (farther) end
tip=tube.get_positions()[tip_atom]
tube.rotate(append(tip[:-1], 0), append(center[0], zeros(2)), center=center) #rotate so that the tip is slanted toward x-axis (center[0],0,0)
tube.center()
setattr(tube, 'dimensions', [tube.get_cell()[0, 0]/2,tube.get_cell()[-1,-1]])
cell=tube.get_cell()
if TYPE!='bare':
if RELOAD==1:
print 'Recomputing bonds'
io.write(str(name), tube)
mol = MoleculeFile.readMolecule(str(name))
print 'Adding hydrogens'
mol.addHydrogens()
if TYPE=='left lead':
print 'Removing hydrogens from the right side'
for atom in mol.atoms[:]:
if atom.pos[2]<center[2]:
mol.removeHydrogens(atom)
elif TYPE=='right lead':
print 'Removing hydrogens from the left side'
for atom in mol.atoms[:]:
if atom.pos[2]>center[2]:
mol.removeHydrogens(atom)
MoleculeFile.writeMolecule(mol,str(name))
tube=io.read(str(name))
else:
tube.set_cell(cell)
return(tube)
You're doing
tube=io.read(str(name))
if
TYPE!='bare'
So in that case you wouldn't get the dimensions. Could this be why you're having the problem?
Also, have you tried just doing
tube.dimensions = [tube.get_cell()[0, 0] / 2, tube.get_cell()[-1,-1]]
instead of setattr? It's only needed when the name of the attribute to change is stored in a variable name.

Categories