diff --git a/pxr/usdImaging/lib/usdviewq/__init__.py b/pxr/usdImaging/lib/usdviewq/__init__.py index 34174515cb..9176296ecc 100644 --- a/pxr/usdImaging/lib/usdviewq/__init__.py +++ b/pxr/usdImaging/lib/usdviewq/__init__.py @@ -79,6 +79,15 @@ def RegisterOptions(self, parser): dest='primPath', type=str, help='A prim path to initially select and frame') + parser.add_argument('--camera', action='store', default="main_cam", + type=str, help="Which camera to set the view to on " + "open - may be given as either just the camera's " + "prim name (ie, just the last element in the prim " + "path), or as a full prim path. Note that if only " + "the prim name is used, and more than one camera " + "exists with the name, which is used will be" + "effectively random") + parser.add_argument('--mask', action='store', dest='populationMask', metavar='PRIMPATH[,PRIMPATH...]', @@ -152,6 +161,36 @@ def ValidateOptions(self, arg_parse_result): arg_parse_result.populationMask = ( arg_parse_result.populationMask.replace(',', ' ').split()) + # convert the camera result to an sdf path, if possible, and verify + # that it is "just" a prim path + if arg_parse_result.camera: + from pxr import Sdf + camPath = Sdf.Path(arg_parse_result.camera) + if camPath.isEmpty: + print >> sys.stderr, "ERROR: invalid camera path - %r" % \ + (arg_parse_result.camera,) + return False + if not camPath.IsPrimPath(): + print >> sys.stderr, "ERROR: invalid camera path - must be a " \ + "raw prim path, without variant " \ + "selections, relational attributes, etc " \ + "- got: %r" % \ + (arg_parse_result.camera,) + return False + + # check if it's a path, or just a name... + if camPath.name != arg_parse_result.camera: + # it's a "real" path, store the SdfPath version + if not camPath.IsAbsolutePath(): + # perhaps we should error here? For now just pre-pending + # root, and printing warning... + print >> sys.stderr, "WARNING: camera path %r was not " \ + "absolute, prepending %r to make " \ + "it absolute" % \ + (str(camPath), + str(Sdf.Path.absoluteRootPath)) + camPath = camPath.MakeAbsolutePath(Sdf.Path.absoluteRootPath) + arg_parse_result.camera = camPath return True def __LaunchProcess(self, arg_parse_result): diff --git a/pxr/usdImaging/lib/usdviewq/mainWindow.py b/pxr/usdImaging/lib/usdviewq/mainWindow.py index 2efc549b17..851fb34c32 100644 --- a/pxr/usdImaging/lib/usdviewq/mainWindow.py +++ b/pxr/usdImaging/lib/usdviewq/mainWindow.py @@ -300,6 +300,12 @@ def __init__(self, parent, parserData): self._timeSamples = None self._stageView = None self._startingPrimCamera = None + if isinstance(parserData.camera, Sdf.Path): + self._startingPrimCameraName = None + self._startingPrimCameraPath = parserData.camera + else: + self._startingPrimCameraName = parserData.camera + self._startingPrimCameraPath = None self.setWindowTitle(parserData.usdFile) self._statusBar = QtGui.QStatusBar(self) @@ -2685,14 +2691,35 @@ def _refreshCameraListAndMenu(self, preserveCurrCamera): preserveCurrCamera = False if not preserveCurrCamera: - for camera in self._allSceneCameras: - # XXX This logic needs to be de-pixarified. Perhaps - # a "primaryCamera" attribute on UsdGeomCamera? - if camera.GetName() == "main_cam": - self._startingPrimCamera = currCamera = camera - if self._stageView: - self._stageView.setCameraPrim(camera) - break + cameraWasSet = False + def setCamera(camera): + self._startingPrimCamera = currCamera = camera + if self._stageView: + self._stageView.setCameraPrim(camera) + cameraWasSet = True + + if self._startingPrimCameraPath: + prim = self._stage.GetPrimAtPath(self._startingPrimCameraPath) + if not prim.IsValid(): + msg = sys.stderr + print >> msg, "WARNING: Camera path %r did not exist in " \ + "stage" % (str(self._startingPrimCameraPath),) + self._startingPrimCameraPath = None + elif not prim.IsA(UsdGeom.Camera): + msg = sys.stderr + print >> msg, "WARNING: Camera path %r was not a " \ + "UsdGeom.Camera" % \ + (str(self._startingPrimCameraPath),) + self._startingPrimCameraPath = None + else: + setCamera(prim) + + if not cameraWasSet and self._startingPrimCameraName: + for camera in self._allSceneCameras: + if camera.GetName() == self._startingPrimCameraName: + setCamera(camera) + break + # Now that we have the current camera and all cameras, build the menu self._ui.menuCamera.clear() for camera in self._allSceneCameras: