Howdy guys i’m currently working on a python script and was wondering if you guys could take a look! I am still running into a few problems but here it is
import maya.cmds as cmds
def findAllCameras(): #function
Listcamnew = [] # main list that needs to be filled
listofCamerasWShapes = cmds.ls(cameras = 1) #lists all the cameras
CameraPar = cmds.listRelatives(listofCamerasWShapes, parent=1) # lists all cameras
DefaultCam = (u'front', u'persp', u'side', u'top') #list all cameras that i don't want
for callcam in CameraPar:
if DefaultCam in CameraPar: #if its a default camera it removes it
str_list.remove(DefaultCam)
return CameraPar
camname = callcam.name #creates name to go into ListcameraNew
Cameragetval = cmds.getAttr(('callcam') + '.translate') #XYZ camera loc
Cameraxyz(a,b,c) = [callcam[0] (a, b, c)] #Clean Val into cameraxyz
StackingValuesofCamera = [camname, Cameraxyz] #stack together
Listcamnew.append(StackingValuesofCamera)
return CameraPar
one of the few problems i’m running into is the function getAttr from maya’s cmds. the result it gives me is [(2.3, 44, 54)] which is a tuple within a list. I was hoping to find a way to extract the tuple out of the list but seems like it doesn’t run correctly by doing Cameraxyz(a,b,c) = [callcam[0] (a, b, c)]
I think there may be a few more problems with the script and its not so called “pythonic” however babysteps first =D,
thank you for the look and thank you doubly for some pointers or advice!
Hi, I haven’t had much time to look at this and I’m very new to Python myself but I’ve got one suggestion.
xform could be used here instead of getAttr, if that helps. You could use cameraPos = cmds.xform (query=True, translate=True, ws=True) to get the world space translate values - that might make your code cleaner, as it will condense it into a list minus the tuple and you can use indexes to get the values. (If that’s what you’re trying to do).
Okay, I had a closer look at the script. Not sure what you’re trying to achieve. Looks like to me you want to pass out a list containing the name of the any cameras that aren’t default (as a string), and the world space position of those cameras. Correct?
import maya.cmds as cmds
def findAllCameras(): #function
listOfCameras = [] # main list that needs to be fille
listofCamerasWShapes = cmds.ls(cameras = 1) #lists all the camera
CameraPar = cmds.listRelatives(listofCamerasWShapes, parent=1) # lists all cameras
DefaultCam = ['front','persp','side','top'] #list all cameras that i don't want
for callcam in DefaultCam: # remove default cameras in the scene from CameraPar
CameraPar.remove(callcam)
#error check
if CameraPar == []:
cmds.error("Empty list. No other cameras in scene")
for c in CameraPar: #getting remaining cameras in scene
Cameraxyz = cmds.xform(c, q=True, ws=True, t=True)
StackingValuesofCamera = (c, Cameraxyz) #create a tuple with camera name and world space Pos
listOfCameras.append(StackingValuesofCamera) #append to a list to pass out
return listOfCameras
This is what I noticed.
You declare DefaultCamera as a tuple with unicode strings in it. This is probably not what you want, so I changed it to a defined list of strings with the known camera names. This means it’s easier to iterate through.
You use for x in y, but don’t actually use x - meaning this part of the code doesn’t really do what it’s meant to do, which is iterate through values in a list.
I put in an error check to break the code if the list, once the cameras are removed, is returned as an empty list.
There are things I removed and cleaned up, because I didn’t understand what they were doing to be honest! Haha! I’m really new at Python too (only a couple of weeks experience) so I don’t know if what I’m doing is right either.
Apologies if this isn’t what you wanted. If it’s not, please say what the script is for and I’ll have another look.
is incorrect. To python you’re mapping a function to something completely random.
If callcam is [(2.3, 44, 54)], then you can simply run
cameraXYZ = callcam[0]
That’ll give you the tuple from the list, because callcam[0] returns the first item which is the tuple.
also just modified your code a little so the function ends if no camera’s exist.
import maya.cmds as cmds
def findAllCameras():
camList = []
CameraPar=[cam for cam in cmds.listRelatives(cmds.ls(cameras=1),parent=1) if cam not in ['front','persp','side','top']]
if CameraPar == []:
cmds.error("Empty list. No other cameras in scene")
return False
for c in CameraPar:
camTran = cmds.xform(c, q=True, ws=True, t=True)
StackingValuesofCamera = (c, camTran)
camList.append(StackingValuesofCamera)
return camList
That way the function ends processing if the CameraPar is empty. It’ll also let you use the function as an object in other functions:
eg
if findAllCamera()=False:
do this....
else:
do that
if CameraPar == []:
cmds.error("Empty list. No other cameras in scene")
return False
[/QUOTE]
I assume this works for the given example (I haven’t run it), but Maya has a tendency to return either empty lists or None depending on which command you use. And sometimes, when you’re really lucky, it will return different ones for the same command under different conditions. As a rule of thumb, it’s probably better to just test the variable if it returns True.
if not CameraPar:
cmds.error("Empty list. No other cameras in scene")
return False
In python empty lists and None both evaluate to False, while lists with items in them will evaluate to True. So this is a more fail-proof way of using python with Maya.
[QUOTE=ldunham1;17144]Just wondering, why the need for ‘return False’ if cmds.error() terminates the code anyway?
Incase its caught?[/QUOTE]
Does cmds.error terminate the script? I assumed it just printed an error to the script window, but kept the script running?
[QUOTE=assumptionsoup;17145]
if not CameraPar:
cmds.error("Empty list. No other cameras in scene")
return False
In python empty lists [] and None both evaluate to False, while lists with items in them will evaluate to True. So this is a more fail-proof way of using python with Maya.[/QUOTE]
Yeah you’re right. if not is a much better way to do it, and far more readable to boot.
[QUOTE=dgovil;17149]Does cmds.error terminate the script? I assumed it just printed an error to the script window, but kept the script running?
[/QUOTE]
error does terminate the script but your method is a lot more readable.
[QUOTE=Wuffles;17150]error does terminate the script but your method is a lot more readable.[/QUOTE]
No, it isn’t. Raise a damn exception. You’re writing python, use it!
Maya has a tendency to return either empty lists or None depending on which command you use
Yup, and what a cause for frustration. I now either use pymel (which has been pretty consistent) or do:
myvar = cmds.ls() or []
for o in myvar:
...
Have the “or ” means I don’t have to check if myvar evaluates to False, which means less nesting and nicer code. Just a suggestion to get around such a heinous ‘design’.
[QUOTE=Wuffles;17580]Sorry for digging up an older thread Rob but I just noticed this. What do you mean by this? Excuse my ignorance as I’m very new to all this. :o)[/QUOTE]
Hi. I’m also pretty new to all of this but I think he meant something along these lines:
Python can raise many different errors / exception , you can check the doc here
so for example raise RuntimeError (“blablablabla”)
(if i didnt miss any capital letters etc should run )
The thing i dont like in the latest versions of maya all those errors cmds.error ,raise etc dont show up red in the bottom line (sorry dont remember the name)
So what I ended up using was a quick call to the API with OpenMaya.MGlobal.displayError(“blablabla”) that shows up red