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);
        }
    }
}
Exemple #2
0
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;    
}