Example #1
0
void
UsdSkel_CacheImpl::ReadScope::_RecursivePopulate(const UsdPrim& prim,
                                                 SkinningQueryKey key,
                                                 UsdSkelAnimQuery animQuery,
                                                 size_t depth)
{
    if(!prim.IsA<UsdGeomImageable>()) {
        TF_DEBUG(USDSKEL_CACHE).Msg(
            "[UsdSkelCache]: %sPruning traversal at <%s> "
            "(prim types is not a UsdGeomImageable)\n",
            _MakeIndent(depth).c_str(), prim.GetPath().GetText());
        return;
    }
        
    TF_DEBUG(USDSKEL_CACHE).Msg("[UsdSkelCache]: %sVisiting <%s>\n",
                                _MakeIndent(depth).c_str(), 
                                prim.GetPath().GetText());

    UsdSkelBindingAPI binding(prim);

    if(UsdRelationship rel = binding.GetAnimationSourceRel()) {
        SdfPathVector targets;
        if(rel.GetForwardedTargets(&targets)) {
            animQuery = FindOrCreateAnimQuery(_GetFirstTarget(rel, targets));
        }
    }

    if(UsdRelationship rel = binding.GetSkeletonRel()) {
        SdfPathVector targets;
        if(rel.GetForwardedTargets(&targets)) {
            _PrimToSkelQueryMap::accessor a;
            if(_cache->_skelQueryCache.insert(a, prim)) {
                a->second = _FindOrCreateSkelQuery(
                    _GetFirstTarget(rel, targets), animQuery);
            }
            key.skelQuery = a->second;

            TF_DEBUG(USDSKEL_CACHE).Msg(
                "[UsdSkelCache]: %sNew skeleton bound at <%s>: %s\n",
                _MakeIndent(depth).c_str(), prim.GetPath().GetText(),
                key.skelQuery.GetDescription().c_str());
        }
    }

    if(UsdAttribute attr = binding.GetJointIndicesAttr())
        key.jointIndicesAttr = attr;

    if(UsdAttribute attr = binding.GetJointWeightsAttr())
        key.jointWeightsAttr = attr;

    if(UsdAttribute attr = binding.GetGeomBindTransformAttr())
        key.geomBindTransformAttr = attr;

    if(UsdAttribute attr = binding.GetJointsAttr()) {
        VtTokenArray jointOrder;
        if(attr.Get(&jointOrder)) {
            key.jointOrder = jointOrder;
        }
    }

    if(prim.IsA<UsdGeomBoundable>() &&
       (key.jointIndicesAttr && key.jointWeightsAttr)) {

        _PrimToSkinningQueryMap::accessor a;
        if(_cache->_primSkinningQueryCache.insert(a, prim)) {
            a->second = _FindOrCreateSkinningQuery(prim, key);
        }

        TF_DEBUG(USDSKEL_CACHE).Msg(
            "[UsdSkelCache]: %sFound skinnable prim <%s> (valid? %d)\n",
            _MakeIndent(depth).c_str(), prim.GetPath().GetText(),
            a->second.IsValid());

        // Skinnable prims cannot be nested.
        return;
    }

    UsdPrim traversalPrim = !prim.IsInstance() ? prim : prim.GetMaster();
    for(const auto& child : prim.GetChildren()) {
        _RecursivePopulate(child, key, animQuery, depth+1);
    }
}