UsdGeomCamera GusdOBJ_usdcamera::_LoadCamera(fpreal t, int thread) { /* XXX: Disallow camera loading until the scene has finished loading. What happens otherwise is that some parm values are pulled on during loading, causing a _LoadCamera request. If this happens before the node's parm values have been loaded, then we'll end up loading the camera using defaults (which reference the shot conversion). So if we don't block this, we end up always loading the shot conversion, even if we don't need it! */ if(_isLoading) return UsdGeomCamera(); /* Always return a null camera while saving. This is to prevent load errors from prematurely interrupting saves, which can lead to corrupt files.*/ if(GusdUTverify_ptr(OPgetDirector())->getIsDoingExplicitSave()) return UsdGeomCamera(); { UT_AutoReadLock readLock(_lock); if(!_camParmsMicroNode.requiresUpdate(t)) return _cam; } UT_AutoWriteLock writeLock(_lock); /* Other thread may already have loaded the cam, so only update if needed.*/ if(_camParmsMicroNode.updateIfNeeded(t, thread)) { _errors.clearAndDestroyErrors(); _cam = UsdGeomCamera(); GusdPRM_Shared prmShared; UT_String usdPath, primPath; evalStringT(usdPath, prmShared->filePathName.getToken(), 0, t, thread); evalStringT(primPath, prmShared->primPathName.getToken(), 0, t, thread); GusdUT_ErrorManager errMgr(_errors); GusdUT_ErrorContext err(errMgr); GusdStageCacheReader cache; if(UsdPrim prim = cache.GetPrimWithVariants( usdPath, primPath, GusdStageOpts::LoadAll(), &err).first) { // Track changes to the stage (eg., reloads) DEP_MicroNode* stageMicroNode = cache.GetStageMicroNode(prim.GetStage()); UT_ASSERT_P(stageMicroNode); _camParmsMicroNode.addExplicitInput(*stageMicroNode); _cam = GusdUSD_Utils::MakeSchemaObj<UsdGeomCamera>(prim, &err); return _cam; } } return UsdGeomCamera(); }
bool GusdUSD_StageProxy::_Load(ScopedLock& lock, UsdStage::InitialLoadSet loadSet, const UnorderedPathSet* pathsToLoad, GusdUT_ErrorContext* err) { if(!_microNode.requiresUpdate(0)) { /* XXX: Errors copied will currently only include errors, not warning. This is because TfErrorMark, which is being used to capture USD errors, is currently not able to capture warnings. This means that in the event that the stage is valid, very little work will be done. This is expected to change in Tf eventually, in which case every stage lookup may involve an excess amount of warning copying on every lookup, possibly impacting performance. May need to revisit this approach of copying all errors when Tf starts allowing warnings to be captured.*/ if(err) _CopyErrors(*err); if(pathsToLoad && _primLoader) { if(_primLoader->LoadIfNeeded(lock, *pathsToLoad, _stage, /*have lock*/ false)) lock.DowngradeToReader(); } return _stage; } if(lock.UpgradeToWriter() || _microNode.requiresUpdate(0)) { /* Mark the proxy clean, so that we don't attempt to load again even if loading has failed. To attempt to reload, the node should be dirtied with MarkDirty() prior to the next load attempt.*/ _microNode.update(0); _errors.clearAndDestroyErrors(); GusdUT_ErrorManager errMgr(_errors); GusdUT_TfErrorScope scope(errMgr); if(_stage) { /* Asking to load when we already have a stage means we should reload the stage.*/ _Reload(_stage); lock.DowngradeToReader(); // XXX: Can reloading fail? return true; } if(SdfLayerRefPtr rootLyr = SdfLayer::FindOrOpen(_key->path.GetString())) { // Load the stage from the cache. UsdStageCacheContext ctx(_cache.GetCache()); if(UsdStageRefPtr stage = UsdStage::Open( rootLyr, _key->sessionLyr, _key->resolverCtx, loadSet)) { _realPath = TfToken(TfRealPath( _key->path)); struct stat attrib; if( stat(_realPath.GetText(), &attrib) == 0 ) { _mtime = attrib.st_mtime; } UT_ASSERT(_cache.GetCache().Contains(stage)); _stage = stage; _InitLoadSet(loadSet); _stageData.Update(stage); if(pathsToLoad && _primLoader) { _primLoader->Load(SdfPathSet(pathsToLoad->begin(), pathsToLoad->end()), stage); } } } else { /* Sdf doesn't throw errors here, so we need to report the failure ourselves.*/ UT_WorkBuffer buf; buf.sprintf("Failed to open layer: %s", _key->path.GetString().c_str()); GusdUT_LogGenericError(_errors, buf.buffer()); } } if(err) _CopyErrors(*err); lock.DowngradeToReader(); return _stage; }