Ejemplo n.º 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);
    }
}
Ejemplo n.º 2
0
bool
UsdSkel_CacheImpl::ReadScope::Populate(const UsdSkelRoot& root)
{
    TRACE_FUNCTION();

    TF_DEBUG(USDSKEL_CACHE).Msg("[UsdSkelCache] Populate map from <%s>\n",
                                root.GetPrim().GetPath().GetText());

    if(!root) {
        TF_CODING_ERROR("'root' is invalid.");
        return false;
    }

    std::vector<std::pair<SkinningQueryKey,UsdPrim> > stack(1);

    UsdPrimRange range =
        UsdPrimRange::PreAndPostVisit(root.GetPrim(),
                                      UsdPrimDefaultPredicate);
                                      // UsdPrimIsInstance);

    for (auto it = range.begin(); it != range.end(); ++it) {
        
        if (it.IsPostVisit()) {
            if (stack.size() > 0 && stack.back().second == *it) {
                stack.pop_back();
            }
            continue;
        }

        if (ARCH_UNLIKELY(!it->IsA<UsdGeomImageable>())) {
            TF_DEBUG(USDSKEL_CACHE).Msg(
                "[UsdSkelCache]  %sPruning traversal at <%s> "
                "(prim is not UsdGeomImageable)\n",
                _MakeIndent(stack.size()).c_str(), it->GetPath().GetText());

            it.PruneChildren();
            continue;
        }

        // TODO: Consider testing whether or not the API has been applied first.
        UsdSkelBindingAPI binding(*it);

        SkinningQueryKey key(stack.back().first);

        UsdSkelSkeleton skel;
        if (binding.GetSkeleton(&skel))
            key.skel = skel.GetPrim();

        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())
            key.jointsAttr = attr;

        if (UsdAttribute attr = binding.GetBlendShapesAttr())
            key.blendShapesAttr = attr;

        if (UsdRelationship rel = binding.GetBlendShapeTargetsRel())
            key.blendShapeTargetsRel = rel;

        if (UsdSkelIsSkinnablePrim(*it)) {

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

            TF_DEBUG(USDSKEL_CACHE).Msg(
                "[UsdSkelCache] %sAdded skinning query for prim <%s>\n",
                _MakeIndent(stack.size()).c_str(),
                it->GetPath().GetText());

            // TODO: How should nested skinnable primitives be handled?
            // Should we prune traversal at this point?
        }

        stack.emplace_back(key, *it);
    }
    return true;
}