static void _AddClipsFromPrimIndex( const PcpPrimIndex& primIndex, std::vector<Usd_ClipCache::Clips>* clips) { std::vector<Usd_ResolvedClipInfo> clipInfo; if (!Usd_ResolveClipInfo(primIndex, &clipInfo)) { return; } for (const Usd_ResolvedClipInfo& entry : clipInfo) { Usd_ClipCache::Clips entryClips; _AddClipsFromClipInfo(primIndex.GetPath(), entry, &entryClips); if (!entryClips.valueClips.empty()) { clips->push_back(entryClips); } } }
static void _AddClipsFromNode(const PcpPrimIndex& primIndex, Usd_ClipCache::Clips* clips) { Usd_ResolvedClipInfo clipInfo; auto node = Usd_ResolveClipInfo(primIndex, &clipInfo); // If we haven't found all of the required clip metadata we can just // bail out. Note that clipTimes and clipManifestAssetPath are *not* // required. if (!clipInfo.clipAssetPaths || !clipInfo.clipPrimPath || !clipInfo.clipActive) { return; } // The clip manifest is currently optional but can greatly improve // performance if specified. For debugging performance problems, // issue a message indicating if one hasn't been specified. if (!clipInfo.clipManifestAssetPath) { TF_DEBUG(USD_CLIPS).Msg( "No clip manifest specified for prim <%s>. " "Performance may be improved if a manifest is specified.", primIndex.GetPath().GetString().c_str()); } // XXX: Possibly want a better way to inform consumers of the error // message.. std::string error; if (!_ValidateClipFields( *clipInfo.clipAssetPaths, *clipInfo.clipPrimPath, *clipInfo.clipActive, &error)) { TF_WARN( "Invalid clips specified for prim <%s> in LayerStack %s: %s", node.GetPath().GetString().c_str(), TfStringify(node.GetLayerStack()).c_str(), error.c_str()); return; } // If a clip manifest has been specified, create a clip for it. if (clipInfo.clipManifestAssetPath) { const Usd_ClipRefPtr clip(new Usd_Clip( /* clipSourceNode = */ node, /* clipSourceLayerIndex = */ clipInfo.indexOfLayerWhereAssetPathsFound, /* clipAssetPath = */ *clipInfo.clipManifestAssetPath, /* clipPrimPath = */ SdfPath(*clipInfo.clipPrimPath), /* clipStartTime = */ Usd_ClipTimesEarliest, /* clipEndTime = */ Usd_ClipTimesLatest, /* clipTimes = */ Usd_Clip::TimeMappings())); clips->manifestClip = clip; } // Generate a mapping of startTime -> clip entry. This allows us to // quickly determine the (startTime, endTime) for a given clip. typedef std::map<double, Usd_ClipEntry> _TimeToClipMap; _TimeToClipMap startTimeToClip; for (const auto& startFrameAndClipIndex : *clipInfo.clipActive) { const double startFrame = startFrameAndClipIndex[0]; const int clipIndex = (int)(startFrameAndClipIndex[1]); const SdfAssetPath& assetPath = (*clipInfo.clipAssetPaths)[clipIndex]; Usd_ClipEntry entry; entry.startTime = startFrame; entry.clipAssetPath = assetPath; entry.clipPrimPath = SdfPath(*clipInfo.clipPrimPath); // Validation should have caused us to bail out if there were any // conflicting clip activations set. TF_VERIFY(startTimeToClip.insert( std::make_pair(entry.startTime, entry)).second); } // Build up the final vector of clips. const _TimeToClipMap::const_iterator itBegin = startTimeToClip.begin(); const _TimeToClipMap::const_iterator itEnd = startTimeToClip.end(); _TimeToClipMap::const_iterator it = startTimeToClip.begin(); while (it != itEnd) { const Usd_ClipEntry clipEntry = it->second; const Usd_Clip::ExternalTime clipStartTime = (it == itBegin ? Usd_ClipTimesEarliest : it->first); ++it; const Usd_Clip::ExternalTime clipEndTime = (it == itEnd ? Usd_ClipTimesLatest : it->first); // Generate the clip time mapping that applies to this clip. Usd_Clip::TimeMappings timeMapping; if (clipInfo.clipTimes) { for (const auto& clipTime : *clipInfo.clipTimes) { const Usd_Clip::ExternalTime extTime = clipTime[0]; const Usd_Clip::InternalTime intTime = clipTime[1]; if (clipStartTime <= extTime && extTime < clipEndTime) { timeMapping.push_back( Usd_Clip::TimeMapping(extTime, intTime)); } } } const Usd_ClipRefPtr clip(new Usd_Clip( /* clipSourceNode = */ node, /* clipSourceLayerIndex = */ clipInfo.indexOfLayerWhereAssetPathsFound, /* clipAssetPath = */ clipEntry.clipAssetPath, /* clipPrimPath = */ clipEntry.clipPrimPath, /* clipStartTime = */ clipStartTime, /* clipEndTime = */ clipEndTime, /* clipTimes = */ timeMapping)); clips->valueClips.push_back(clip); } clips->sourceNode = node; clips->sourceLayerIndex = clipInfo.indexOfLayerWhereAssetPathsFound; }