@@ -403,7 +403,7 @@ def __init__(self, parserData, resolverContextFn):
403403 self ._ui = Ui_MainWindow ()
404404 self ._ui .setupUi (self ._mainWindow )
405405
406- self ._mainWindow .setWindowTitle (parserData .usdFile )
406+ self ._mainWindow .setWindowTitle (parserData .usdFile or "New Stage" )
407407 self ._statusBar = QtWidgets .QStatusBar (self ._mainWindow )
408408 self ._mainWindow .setStatusBar (self ._statusBar )
409409
@@ -1203,17 +1203,22 @@ def _MuteMatchingLayers():
12031203 # layers populated after loading
12041204 _MuteMatchingLayers ()
12051205
1206- def _openStage (self , usdFilePath , sessionFilePath ,
1207- populationMaskPaths , muteLayersRe ):
1206+ def _openEmptyStage (self ):
1207+ stage = Usd .Stage .CreateInMemory ()
1208+
1209+ if not stage :
1210+ sys .stderr .write ('Error: Unable to create empty stage\n ' )
1211+
1212+ return stage
1213+
1214+ def _openStageForFile (self , usdFilePath , sessionFilePath ,
1215+ populationMaskPaths , muteLayersRe ):
12081216
12091217 def _GetFormattedError (reasons = None ):
12101218 err = ("Error: Unable to open stage '{0}'\n " .format (usdFilePath ))
12111219 if reasons :
12121220 err += "\n " .join (reasons ) + "\n "
12131221 return err
1214-
1215- if self ._mallocTags != 'none' :
1216- Tf .MallocTag .Initialize ()
12171222
12181223 # Pull on the asset resolver here so that the "open stage" time does
12191224 # not include its initialization time for consistency with previous
@@ -1276,6 +1281,21 @@ def _GetFormattedError(reasons=None):
12761281 else :
12771282 stage .SetEditTarget (stage .GetSessionLayer ())
12781283
1284+ return stage
1285+
1286+ def _openStage (self , usdFilePath , sessionFilePath ,
1287+ populationMaskPaths , muteLayersRe ):
1288+
1289+ if self ._mallocTags != 'none' :
1290+ Tf ._mallocTags .Initialize ()
1291+
1292+ if not usdFilePath :
1293+ stage = self ._openEmptyStage ()
1294+
1295+ else :
1296+ stage = self ._openStageForFile (usdFilePath , sessionFilePath ,
1297+ populationMaskPaths , muteLayersRe )
1298+
12791299 if self ._mallocTags == 'stage' :
12801300 DumpMallocTags (stage , "stage-loading" )
12811301
@@ -2795,6 +2815,12 @@ def _cleanAndClose(self):
27952815
27962816 # Start timer to measure Qt shutdown time
27972817 self ._startQtShutdownTimer ()
2818+
2819+
2820+ def _getRecommendedFilenamePrefix (self ):
2821+ return (self ._parserData .usdFile .rsplit ('.' , 1 )[0 ]
2822+ if self ._parserData .usdFile
2823+ else 'new_file' )
27982824
27992825 def _openFile (self ):
28002826 extensions = Sdf .FileFormat .FindAllFileFormatExtensions ()
@@ -2836,14 +2862,17 @@ def _getSaveFileName(self, caption, recommendedFilename):
28362862 return saveName
28372863
28382864 def _saveOverridesAs (self ):
2839- recommendedFilename = self ._parserData .usdFile .rsplit ('.' , 1 )[0 ]
2840- recommendedFilename += '_overrides.usd'
2865+ recommendedFilename = self ._getRecommendedFilenamePrefix ()
2866+ if self ._parserData .usdFile :
2867+ recommendedFilename += "_overrides.usd"
2868+ else :
2869+ recommendedFilename += ".usd"
28412870
28422871 saveName = self ._getSaveFileName (
28432872 'Save Overrides As' , recommendedFilename )
28442873 if len (saveName ) == 0 :
28452874 return
2846- elif (os .path .isfile (saveName ) and
2875+ elif (os .path .isfile (saveName ) and self . _parserData . usdFile and
28472876 os .path .samefile (saveName , self ._parserData .usdFile )):
28482877 msg = QtWidgets .QMessageBox ()
28492878 msg .setIcon (QtWidgets .QMessageBox .Critical )
@@ -2857,13 +2886,13 @@ def _saveOverridesAs(self):
28572886 return
28582887
28592888 with BusyContext ():
2860- # In the future, we may allow usdview to be brought up with no file,
2861- # in which case it would create an in-memory root layer, to which
2862- # all edits will be targeted. In order to future proof
2863- # this, first fetch the root layer, and if it is anonymous, just
2864- # export it to the given filename. If it isn't anonmyous (i.e., it
2865- # is a regular usd file on disk), export the session layer and add
2866- # the stage root file as a sublayer.
2889+ # usdview can be brought up with no file, in which case it
2890+ # creates an in-memory root layer, to which all edits are
2891+ # targeted. This first fetches the root layer, and if it is
2892+ # anonymous, just exports it to the given filename. If it
2893+ # isn't anonymous (i.e., it is a regular usd file on disk),
2894+ # exports the session layer and add the stage root file
2895+ # as a sublayer.
28672896 rootLayer = self ._dataModel .stage .GetRootLayer ()
28682897 if not rootLayer .anonymous :
28692898 self ._dataModel .stage .GetSessionLayer ().Export (
@@ -2889,7 +2918,7 @@ def _saveOverridesAs(self):
28892918 saveName , 'Created by UsdView' )
28902919
28912920 def _saveFlattenedAs (self ):
2892- recommendedFilename = self ._parserData . usdFile . rsplit ( '.' , 1 )[ 0 ]
2921+ recommendedFilename = self ._getRecommendedFilenamePrefix ()
28932922 recommendedFilename += '_flattened.usd'
28942923
28952924 saveName = self ._getSaveFileName (
@@ -2905,7 +2934,7 @@ def _copyViewerImage(self):
29052934
29062935 def _saveViewerImage (self ):
29072936 recommendedFilename = "{}_{}{:04d}.png" .format (
2908- self ._parserData . usdFile . rsplit ( '.' , 1 )[ 0 ] ,
2937+ self ._getRecommendedFilenamePrefix () ,
29092938 "" if not self .getActiveCamera ()
29102939 else self .getActiveCamera ().GetName () + "_" ,
29112940 int (self ._dataModel .currentFrame .GetValue ()))
@@ -5518,4 +5547,4 @@ def setActiveRenderPassPrim(self, prim):
55185547
55195548 if self ._stageView :
55205549 self ._stageView .SetActiveRenderPassPrim (prim )
5521- self ._stageView .updateView ()
5550+ self ._stageView .updateView ()
0 commit comments