Package mrv :: Package maya :: Module scene
[hide private]
[frames] | no frames]

Source Code for Module mrv.maya.scene

  1  # -*- coding: utf-8 -*- 
  2  """ 
  3  Provides methodes to query and alter the currently loaded scene. It covers 
  4  most of the functionality of the 'file' command, but has been renamed to scene 
  5  as disambiguation to a filesystem file. 
  6  """ 
  7  __docformat__ = "restructuredtext" 
  8   
  9  import util as mutil 
 10  import mrv.util as util 
 11  import maya.OpenMaya as api 
 12  import maya.cmds as cmds 
 13  from mrv.path import make_path 
 14   
 15  import inspect 
 16   
 17  __all__ = [ 'Scene' ] 
18 19 20 -class _SceneEvent( mutil.CallbackEventBase ):
21 """ Implements Scene Callbacks""" 22 23 _checkCBSet = set( ( api.MSceneMessage.kBeforeNewCheck, 24 api.MSceneMessage.kBeforeSaveCheck ) ) 25 26 _checkFileCBSet = set( ( api.MSceneMessage.kBeforeImportCheck, 27 api.MSceneMessage.kBeforeOpenCheck, 28 api.MSceneMessage.kBeforeExportCheck, 29 api.MSceneMessage.kBeforeReferenceCheck, 30 api.MSceneMessage.kBeforeLoadReferenceCheck ) ) 31 32 #( Configuration 33 use_weakref = False 34 remove_on_error = True 35 36 weakref_sender = True 37 #) END configuration 38 39 # get the proper registration method
40 - def _getRegisterFunction(self, eventID):
41 reg_method = api.MSceneMessage.addCallback 42 if eventID in self._checkCBSet: 43 reg_method = api.MSceneMessage.addCheckCallback 44 elif eventID in self._checkFileCBSet: 45 reg_method = api.MSceneMessage.addCheckFileCallback 46 # END find registration method 47 return reg_method
48
49 # END SceneEvent 50 51 52 53 -class Scene( util.Singleton, util.EventSender ):
54 """Singleton Class allowing access to the maya scene 55 56 You can register all events available in MSceneMessage easily usnig the following 57 syntax: 58 59 >>> scene.beforeSoftwareRender = myFunctionObject 60 61 """ 62 63 64 kFileTypeMap = { "" : "mayaAscii", # treat untitled scenes as ma 65 ".ma" : "mayaAscii", 66 ".mb" : "mayaBinary" } 67 68 #{ Events 69 sender_as_argument = False 70 71 # create events from 'kEventName', creating a corresponding event named 72 # 'eventName' 73 for eidName, eid in ((n,v) for n,v in inspect.getmembers(api.MSceneMessage) if n.startswith('k')): 74 locals()[util.uncapitalize(eidName[1:])] = _SceneEvent(eid) 75 # END for each message id to create 76 77 #} END events 78 79 80 81 #{ Edit Methods 82 @classmethod
83 - def open( cls, scenepath=None, force=False, **kwargs ):
84 """ Open the scene at the given scenepath 85 86 :param scenepath: The path to the file to be opened 87 If None, the currently loaded file will reopened 88 :param force: if True, the new scene will be loaded although currently 89 loaded contains unsaved changes 90 :param kwargs: passed to *cmds.file* 91 :return: a Path to the loaded scene""" 92 if not scenepath: 93 scenepath = cls.name() 94 95 # NOTE: it will return the last loaded reference instead of the loaded file - lets fix this ! 96 sourcePath = make_path( scenepath ) 97 kwargs.pop('open', kwargs.pop('o', None)) 98 kwargs.pop('force', kwargs.pop('f', None)) 99 lastReference = cmds.file( sourcePath.abspath(), open=1, force=force, **kwargs ) 100 return make_path( sourcePath )
101 102 @classmethod
103 - def new( cls, force = False, **kwargs ):
104 """ Create a new scene 105 106 :param force: if True, the new scene will be created even though there 107 are unsaved modifications 108 :param kwargs: passed to *cmds.file* 109 :return: Path with name of the new file""" 110 kwargs.pop('new', kwargs.pop('n', None)) 111 kwargs.pop('force', kwargs.pop('f', None)) 112 return make_path( cmds.file( new = True, force = force, **kwargs ) )
113 114 @classmethod
115 - def rename( cls, scenepath ):
116 """Rename the currently loaded file to be the file at scenepath 117 118 :param scenepath: string or Path pointing describing the new location of the scene. 119 :return: Path to scenepath 120 :note: as opposed to the normal file -rename it will also adjust the extension 121 :raise RuntimeError: if the scene's extension is not supported.""" 122 scenepath = make_path(scenepath) 123 try: 124 cmds.file( rename = scenepath.expandvars() ) 125 cmds.file( type = cls.kFileTypeMap[ scenepath.ext() ] ) 126 except KeyError: 127 raise RuntimeError( "Unsupported filetype of: " + scenepath ) 128 # END exception handling 129 130 return scenepath
131 132 @classmethod
133 - def save( cls, scenepath=None, autodeleteUnknown = False, **kwargs ):
134 """Save the currently opened scene under scenepath in the respective format 135 136 :param scenepath: if None, the currently opened scene will be saved, otherwise 137 the name will be changed. Paths leading to the file will automatically be created. 138 :param autodeleteUnknown: if true, unknown nodes will automatically be deleted 139 before an attempt is made to change the maya file's type 140 :param kwargs: passed to cmds.file 141 :return: Path at which the scene has been saved.""" 142 if scenepath is None or scenepath == "": 143 scenepath = cls.name( ) 144 145 scenepath = make_path( scenepath ) 146 curscene = cls.name() 147 try : 148 filetype = cls.kFileTypeMap[ scenepath.ext() ] 149 curscenetype = cls.kFileTypeMap[ curscene.ext() ] 150 except KeyError: 151 raise RuntimeError( "Unsupported filetype of: " + scenepath ) 152 153 # is it a save as ? 154 if curscene != scenepath: 155 cls.rename(scenepath) 156 157 # assure path exists 158 parentdir = scenepath.dirname( ) 159 if not parentdir.exists( ): 160 parentdir.makedirs( ) 161 # END assure parent path exists 162 163 # delete unknown before changing types ( would result in an error otherwise ) 164 if autodeleteUnknown and curscenetype != filetype: 165 cls.deleteUnknownNodes() 166 # END handle unkonwn nodes 167 168 # safe the file 169 kwargs.pop('save', kwargs.pop('s', None)) 170 kwargs.pop('type', kwargs.pop('typ', None)) 171 try: 172 return make_path( cmds.file( save=True, type=filetype, **kwargs ) ) 173 except RuntimeError: 174 if curscene != cls.name(): 175 cls.rename(curscene) 176 # END restore previous name on error 177 raise
178 # END exception handling 179 180 @classmethod
181 - def export(cls, outputFile, nodeListOrIterable=None, **kwargs):
182 """Export the given nodes or everything into the file at path 183 184 :param outputFile: Path object or path string to which the data should 185 be written to. Parent directories will be created as needed 186 :param nodeListOrIterable: if None, everything will be exported. 187 Otherwise it may be an MSelectionList ( recommended ), or a list of 188 Nodes, MObjects or MDagPaths 189 :param kwargs: passed to cmds.file, see the mel docs for modifying flags 190 :return: Path to which the data was exported""" 191 outputFile = make_path(outputFile) 192 if not outputFile.dirname().isdir(): 193 outputFile.dirname().makedirs() 194 # END create parent dirs 195 196 prev_selection = None 197 if nodeListOrIterable is None: 198 kwargs['exportAll'] = True 199 else: 200 # export selected mode 201 kwargs['exportSelected'] = True 202 prev_selection = api.MSelectionList() 203 api.MGlobal.getActiveSelectionList(prev_selection) 204 205 import nt 206 nt.select(nt.toSelectionList(nodeListOrIterable)) 207 # END handle nodes 208 209 typ = kwargs.pop('type', kwargs.pop('typ', cls.kFileTypeMap.get(outputFile.ext(), None))) 210 if typ is None: 211 raise RuntimeError("Invalid type in %s" % outputFile) 212 # END handle type 213 214 try: 215 cmds.file(outputFile, type=typ, **kwargs) 216 return outputFile 217 finally: 218 if prev_selection is not None: 219 api.MGlobal.setActiveSelectionList(prev_selection)
220 # END if we have a selection to restore 221 # END handle selection 222 223 #} END edit methods 224 225 #{ Utilities 226 @classmethod
227 - def deleteUnknownNodes( cls ):
228 """Deletes all unknown nodes in the scene 229 230 :note: only do this if you are about to change the type of the scene during 231 save or export - otherwise the operation would fail if there are still unknown nodes 232 in the scene""" 233 unknownNodes = cmds.ls( type="unknown" ) # using mel is the faatest here 234 if unknownNodes: 235 cmds.delete( unknownNodes )
236 237 #} END utilities 238 239 #{ Query Methods 240 @classmethod
241 - def name( cls ):
242 return make_path( cmds.file( q=1, exn=1 ) )
243 244 @classmethod
245 - def isModified( cls ):
246 return cmds.file( q=1, amf=True )
247 #} END query methods 248 249 250 # END SCENE 251