How to get list of cameras or render global in the scene file without opening in maya

this question is like the most important thing that i want to know, I dont know why its not discussed anywhere, but I am sure their is a way, using python,

can anyone please tell me how can i open the maya scene file<not in maya> with python script get the list of camera or render globals setting make changes to the setting and save back…

because sometimes all it is required to change camera to be rendered or some setting for that opening a heavy scene could be a waste of time…

I would really appreciate for any kind of help…

If it’s a mayaAscii file, you can parse it as a text file and find or add/remove the creation and attribute setting of cameras and renderGlobals.

If it’s a mayaBinary file (or you don’t want to parse a text file), you can use the mayapy.exe python interpreter in maya/bin. It’s a python interpreter with the necessary environment variables set so you can open maya scenes and run python scripts on the open scene.

thats it thanks alot …

Simple template:

import maya.standalone
import maya.cmds as cmds
   
def standalone_template(file_to_open):
    # Start in batch mode
    maya.standalone.initialize(name='python')
 
    cmds.file(file_to_open, f=True, o=True)
 
    # Do your magic here
 
    # Save it
    cmds.file(s=True, f=True)

You would then launch that script with the mayapy interpreter

So I am trying to run the method below from python script [RenderUI.py] and read data returned by it using mayapy but don’t know why i am not getting the correct result even if the logic seems to be right…

def readFile(self):
            ## call to readMayaFile.py using mayapy.exe interpreter
            fileToOpen="I:/scenes/san_telus_pan_v009.ma"
            code_str = \
    """
    import readMayaFile
    readMayaFile.getCams("""+fileToOpen+""")
    """
            # save the code
            phile=os.path.join(os.path.split(__file__)[0],"test.py")
            filename=phile
            fout = open(filename, "w")
            fout.write(code_str)
            fout.close()
            # execute the code with mayapy and pipe the result to a string
            mayapy="D:/Program Files/Autodesk/Maya2013/bin/mayapy.exe"
            test = mayapy+" " + filename
            process = subprocess.Popen(test, shell=True, stdout=subprocess.PIPE)
            process.wait()
            print process.returncode,"<" # 0 = success, optional check
            # read the result to a string
            strRead = process.stdout.read()
            print strRead

the readMayaFile.py contains :


    #mapay interprer file
    import os
    import maya.standalone
    import maya.cmds as cmds

    def getCams(phileToOpen):
        maya.standalone.initialize(name='python')
        cmds.file(phileToOpen, force=True,open=True)
        cams=cmds.ls(type="camera")
        return cams

Can anyone please help me figure out what am I doing wrong in the implementing the logic in readFile() method ?

First off, you might want to just setup a single script rather than writing out to a second file. You can pass arguments in to python and get them back with sys.argv:



if __name__ == "__main__":
    import sys, os
    args = sys.argv

    this_script = args[0]  #this will be the name of this file
    target_file = args[1]  #this would be the first argument you passed in

    import maya.standalone
    maya.standalone.initialize()
    import maya.cmds as cmds
    
    try:
        cmds.file(target_file, open = True, force = True)
        sys.stdout.write(",".join(cmds.ls(type='camera')))
        quit()
    except RuntimeError:
        sys.stderr.write('could not find %s
' % target_file)
        raise

The call pass in filename of the script above and the filename of the file you want to check to your subprocess as arguments

perfect thanks a million …

Hello again Steve,

I decided instead of just returning the cams so i modiefied the code above and retured dictionary in the form of string coz returning dectionary was giving me error


        cmds.file(target_file, open = True, force = True)
        camsLst=cmds.ls(type='camera')
        startFrame=cmds.getAttr("defaultRenderGlobals.startFrame")
        endFrame=cmds.getAttr("defaultRenderGlobals.endFrame")
        stepByFrame=cmds.getAttr("defaultRenderGlobals.byFrameStep")
        defaultRenderer = cmds.getAttr("defaultRenderGlobals.currentRenderer")
        imageFormat = cmds.getAttr("defaultRenderGlobals.imageFormat")
        readItemsObj={'camsLst':camsLst,
        'startFrame':startFrame,
        'endFrame':endFrame,
        'stepByFrame':stepByFrame,
        'defaultRenderer':defaultRenderer,
        'ImageFormat':imageFormat
        }
        print readItemsObj
        sys.stdout.write(str(readItemsObj))

and the other file that receives this data I converted string back to dictionary using ast module

self.objRead = ast.literal_eval(process.stdout.read())

strangely the above code works fine on my laptop but when i tested on my desktop machine i got error saying


Traceback (most recent call last):                                              
  File "E:\Dropbox\Research_Study\myprojects\Batch\RenderUI.py", line 256, in ex
ecMayapy                                                                        
    self.objRead = ast.literal_eval(process.stdout.read())                      
  File "D:\Python26\lib\ast.py", line 48, in literal_eval                       
    node_or_string = parse(node_or_string, mode='eval')                         
  File "D:\Python26\lib\ast.py", line 36, in parse                              
    return compile(expr, filename, mode, PyCF_ONLY_AST)                         
  File "<unknown>", line 1                                                      
                                                                                
    ^                                                                           
SyntaxError: invalid syntax                                                     

is their a better way i can covert string to dictionary or can straight way handle dict object from stdout ?

If you really want to send complex data between processes, try something like pickle or json

[QUOTE=Theodox;19327]If you really want to send complex data between processes, try something like pickle or json[/QUOTE] that would mean write to disk operation?

Not necessarily. Pickle converts objects into a format that can be stored/transmitted. You can still pass pickled (or json) data between processes like you were doing with the stringified dictionary.

write out pickle.dumps() to the stdout

sweet !!!

well, i tried the same with nuke as well got success reading file from nuke but
when i return to stdout.read() i am getting index out of range error
Success Reading : 09_color_correct_track_end.nk
Traceback (most recent call last):
File “\RenderUI.py”, line 384, in execApp
print pickle.loads(process.stdout.read())
File “D:\Python26\lib\pickle.py”, line 1374, in loads
return Unpickler(file).load()
File “D:\Python26\lib\pickle.py”, line 858, in load
dispatchkey
File “D:\Python26\lib\pickle.py”, line 1203, in load_setitems
mark = self.marker()
File “D:\Python26\lib\pickle.py”, line 874, in marker
while stack[k] is not mark: k = k-1
IndexError: list index out of range

just trying to print before i use the data, what else is returned then

this is how I dump with pickle


        try:
            import nuke

            # Open nuke script
            nuke.scriptOpen(target_file)
            wrtNodelst=[]
            allWriteNodes=nuke.allNodes("Write")
            for index,each in enumerate(allWriteNodes):
                wrtNodelst.insert(index, each.name())
            sys.stdout.write(pickle.dumps(wrtNodelst))
            quit()
        except RuntimeError:
          sys.stderr.write('could not find %s
' % target_file)
          raise

is it because i am reading data object that didnt wrote the pickle object ?