void GusdUSD_XformCache::XformInfo::ComputeFlags(const UsdPrim& prim, GusdUSD_XformCache& cache) { if(query.TransformMightBeTimeVarying()) { _flags = FLAGS_LOCAL_MAYBE_TIMEVARYING| FLAGS_WORLD_MAYBE_TIMEVARYING; } else { /* Local transform isn't time-varying, but maybe the parent is.*/ if(!query.GetResetXformStack()) { UsdPrim parent = prim.GetParent(); if(parent && parent.GetPath() != SdfPath::AbsoluteRootPath()) { auto info = cache.GetXformInfo(parent); if(info && info->WorldXformIsMaybeTimeVarying()) _flags = FLAGS_WORLD_MAYBE_TIMEVARYING; } } } if(!query.GetResetXformStack()) { UsdPrim parent = prim.GetParent(); if(parent && parent.GetPath() != SdfPath::AbsoluteRootPath()) _flags |= FLAGS_HAS_PARENT_XFORM; } }
bool UsdGeomPrimvarsAPI::HasPossiblyInheritedPrimvar(const TfToken &name) const { TRACE_FUNCTION(); UsdPrim prim = GetPrim(); if (!prim) { TF_CODING_ERROR("HasPossiblyInheritedPrimvar called on invalid prim: %s", UsdDescribe(prim).c_str()); return false; } UsdGeomPrimvar pv = GetPrimvar(name); if (pv.HasAuthoredValue()){ return true; } const TfToken attrName = UsdGeomPrimvar::_MakeNamespaced(name); if (attrName.IsEmpty()) { return false; } for (prim = prim.GetParent(); prim && !prim.IsPseudoRoot(); prim = prim.GetParent()) { UsdAttribute attr = prim.GetAttribute(attrName); if (attr.HasAuthoredValue() && UsdGeomPrimvar::IsPrimvar(attr)) { // Only constant primvars can be inherited. // Non-constant interpolation blocks inheritance. return UsdGeomPrimvar(attr).GetInterpolation() == UsdGeomTokens->constant; } } return false; }
void UsdRiStatementsAPI::SetCoordinateSystem(const std::string &coordSysName) { UsdAttribute attr = GetPrim().CreateAttribute(_tokens->coordsys, SdfValueTypeNames->String, /* custom = */ false); if (TF_VERIFY(attr)) { attr.Set(coordSysName); UsdPrim currPrim = GetPrim(); while (currPrim && currPrim.GetPath() != SdfPath::AbsoluteRootPath()) { if (currPrim.IsModel() && !currPrim.IsGroup() && currPrim.GetPath() != SdfPath::AbsoluteRootPath()) { UsdRelationship rel = currPrim.CreateRelationship(_tokens->modelCoordsys, /* custom = */ false); if (TF_VERIFY(rel)) { // Order should not matter, since these are a set, // but historically we have appended these. rel.AddTarget(GetPrim().GetPath()); } break; } currPrim = currPrim.GetParent(); } } }
UsdGeomPrimvar UsdGeomPrimvarsAPI::FindPrimvarWithInheritance(const TfToken &name) const { TRACE_FUNCTION(); const TfToken attrName = UsdGeomPrimvar::_MakeNamespaced(name); UsdPrim prim = GetPrim(); if (!prim) { TF_CODING_ERROR("FindPrimvarWithInheritance called on invalid prim: %s", UsdDescribe(prim).c_str()); return UsdGeomPrimvar(); } UsdGeomPrimvar localPv = GetPrimvar(name); if (localPv.HasAuthoredValue()){ return localPv; } for (prim = prim.GetParent(); prim && !prim.IsPseudoRoot(); prim = prim.GetParent()) { UsdAttribute attr = prim.GetAttribute(attrName); if (attr.HasAuthoredValue()) { if (UsdGeomPrimvar pv = UsdGeomPrimvar(attr)) { // Only constant primvars can be inherited. if (pv.GetInterpolation() == UsdGeomTokens->constant) { return pv; } else { // Non-constant interpolation blocks inheritance. return UsdGeomPrimvar(); } } } } return localPv; }
void UsdRiStatementsAPI::SetScopedCoordinateSystem(const std::string &coordSysName) { UsdAttribute attr = GetPrim().CreateAttribute(_tokens->scopedCoordsys, SdfValueTypeNames->String, /* custom = */ false); if (TF_VERIFY(attr)) { attr.Set(coordSysName); UsdPrim currPrim = GetPrim(); while (currPrim) { if (currPrim.IsModel() && !currPrim.IsGroup() && currPrim.GetPath() != SdfPath::AbsoluteRootPath()) { UsdRelationship rel = currPrim.CreateRelationship(_tokens->modelScopedCoordsys, /* custom = */ false); if (TF_VERIFY(rel)) { rel.AddTarget(GetPrim().GetPath()); } break; } currPrim = currPrim.GetParent(); } } }
bool GusdXformWrapper:: initUsdPrim(const UsdStagePtr& stage, const SdfPath& path, bool asOverride) { bool newPrim = true; if( asOverride ) { UsdPrim existing = stage->GetPrimAtPath( path ); if( existing ) { // Note that we are creating a Xformable rather than a Xform. // If we are writing an overlay and the ROP sees a geometry packed prim, // we want to write just the xform. In that case we can use a xform // wrapper to write the xform on any prim type. m_usdXformForWrite = UsdGeomXformable(stage->OverridePrim( path )); newPrim = false; } else { m_usdXformForWrite = UsdGeomXform::Define( stage, path ); // Make sure our ancestors have proper types. UsdPrim p = m_usdXformForWrite.GetPrim().GetParent(); while( p && p.GetTypeName().IsEmpty() ) { UsdGeomXform::Define( stage, p.GetPath() ); p = p.GetParent(); } } } else { m_usdXformForWrite = UsdGeomXform::Define( stage, path ); } if( !m_usdXformForWrite || !m_usdXformForWrite.GetPrim().IsValid() ) { TF_WARN( "Unable to create %s xform '%s'.", newPrim ? "new" : "override", path.GetText() ); } return bool(m_usdXformForWrite); }
static void _RecurseForInheritablePrimvars(const UsdPrim &prim, const TfToken &pvPrefix, std::vector<UsdGeomPrimvar> *primvars, bool acceptAll = false) { if (prim.IsPseudoRoot()) return; // The `acceptAll` override is only useful for the prim we are actually // querying, i.e. the *first* prim on which this function is called _RecurseForInheritablePrimvars(prim.GetParent(), pvPrefix, primvars); _AddPrimToInheritedPrimvars(prim, pvPrefix, primvars, primvars, acceptAll); }
UsdSkelSkeletonQuery UsdSkel_CacheImpl::ReadScope::GetInheritedSkelQuery(const UsdPrim& prim) const { _PrimToSkelQueryMap::const_accessor a; for(UsdPrim p = prim; p; p = p.GetParent()) { if(_cache->_skelQueryCache.find(a, p)) { return a->second; } if(prim.IsA<UsdSkelRoot>()) { break; } } return UsdSkelSkeletonQuery(); }
/// Finds the rootmost ancestor of the prim at \p path that is an Xform /// or SkelRoot type prim. The result may be the prim itself. static UsdPrim _FindRootmostXformOrSkelRoot(const UsdStagePtr& stage, const SdfPath& path) { UsdPrim currentPrim = stage->GetPrimAtPath(path); UsdPrim rootmost; while (currentPrim) { if (currentPrim.IsA<UsdGeomXform>()) { rootmost = currentPrim; } else if (currentPrim.IsA<UsdSkelRoot>()) { rootmost = currentPrim; } currentPrim = currentPrim.GetParent(); } return rootmost; }
bool GusdUSD_XformCache::GetLocalToWorldTransform(const UsdPrim& prim, UsdTimeCode time, UT_Matrix4D& xform) { const auto info = GetXformInfo(prim); if(BOOST_UNLIKELY(!info)) return false; // See if we can remap the time to for unvarying xforms. if(!time.IsDefault() && !info->WorldXformIsMaybeTimeVarying()) { /* XXX: we know we're not time varying, but that doesn't mean that we can key default, since there might still be a single varying value that we'd miss. Key off of time=0 instead.*/ time = UsdTimeCode(0.0); } _VaryingKey key(GusdUSD_VaryingPropertyKey(prim, time)); if(auto item = _worldXforms.findItem(key)) { xform = UTverify_cast<const _CappedXformItem*>(item.get())->xform; return true; } /* XXX: Race is possible when setting computed value, but it's preferable to have multiple threads compute the same thing than to cause lock contention.*/ if(_GetLocalTransformation(prim, time, xform, info)) { if(BOOST_UNLIKELY(!info->HasParentXform())) { _worldXforms.addItem(key, UT_CappedItemHandle( new _CappedXformItem(xform))); return true; } UsdPrim parent = prim.GetParent(); UT_ASSERT_P(parent); UT_Matrix4D parentXf; if(GetLocalToWorldTransform(parent, time, parentXf)) { xform *= parentXf; _worldXforms.addItem( key, UT_CappedItemHandle(new _CappedXformItem(xform))); return true; } } return false; }
/* virtual */ void UsdImagingMaterialAdapter::MarkMaterialDirty(UsdPrim const& prim, SdfPath const& cachePath, UsdImagingIndexProxy* index) { // If this is invoked on behalf of a Shader prim underneath a // Material prim, walk up to the enclosing Material. SdfPath materialCachePath = cachePath; UsdPrim materialPrim = prim; while (materialPrim && !materialPrim.IsA<UsdShadeMaterial>()) { materialPrim = materialPrim.GetParent(); materialCachePath = materialCachePath.GetParentPath(); } if (!TF_VERIFY(materialPrim)) { return; } index->MarkSprimDirty(materialCachePath, HdMaterial::DirtyResource); }
PXR_NAMESPACE_CLOSE_SCOPE // ===================================================================== // // Feel free to add custom code below this line. It will be preserved by // the code generator. // // Just remember to wrap code in the appropriate delimiters: // 'PXR_NAMESPACE_OPEN_SCOPE', 'PXR_NAMESPACE_CLOSE_SCOPE'. // ===================================================================== // // --(BEGIN CUSTOM CODE)-- PXR_NAMESPACE_OPEN_SCOPE UsdSkelRoot UsdSkelRoot::Find(const UsdPrim& prim) { for(UsdPrim p = prim; p; p = p.GetParent()) { if(p.IsA<UsdSkelRoot>()) { return UsdSkelRoot(p); } } return UsdSkelRoot(); }
bool UsdRelationship::GetTargets(SdfPathVector* targets) const { TRACE_FUNCTION(); UsdStage *stage = _GetStage(); PcpErrorVector pcpErrors; std::vector<std::string> otherErrors; PcpTargetIndex targetIndex; { // Our intention is that the following code requires read-only // access to the PcpCache, so use a const-ref. const PcpCache& pcpCache(*stage->_GetPcpCache()); // In USD mode, Pcp does not cache property indexes, so we // compute one here ourselves and use that. First, we need // to get the prim index of the owning prim. const PcpPrimIndex &primIndex = _Prim()->GetPrimIndex(); // PERFORMANCE: Here we can't avoid constructing the full property path // without changing the Pcp API. We're about to do serious // composition/indexing, though, so the added expense may be neglible. const PcpSite propSite(pcpCache.GetLayerStackIdentifier(), GetPath()); PcpPropertyIndex propIndex; PcpBuildPrimPropertyIndex(propSite.path, pcpCache, primIndex, &propIndex, &pcpErrors); PcpBuildTargetIndex(propSite, propIndex, SdfSpecTypeRelationship, &targetIndex, &pcpErrors); } targets->swap(targetIndex.paths); if (!targets->empty() && _Prim()->IsInMaster()) { Usd_PrimDataConstPtr master = get_pointer(_Prim()); while (!master->IsMaster()) { master = master->GetParent(); } // Paths that point to an object under the master's source prim index // are internal to the master and need to be translated to either // the master or instance we're currently looking at. const SdfPath& masterSourcePrimIndexPath = master->GetSourcePrimIndex().GetPath(); if (GetPrim().IsInMaster()) { // Translate any paths that point to an object at or under the // source prim index to our master. for (SdfPath& target : *targets) { target = target.ReplacePrefix( masterSourcePrimIndexPath, master->GetPath()); } } else if (GetPrim().IsInstanceProxy()) { // Translate any paths that point to an object at or under the // source prim index to our instance. UsdPrim instance = GetPrim(); while (!instance.IsInstance()) { instance = instance.GetParent(); } for (SdfPath& target : *targets) { target = target.ReplacePrefix( masterSourcePrimIndexPath, instance.GetPath()); } } } // TODO: handle errors const bool hasErrors = !(pcpErrors.empty() && otherErrors.empty()); if (hasErrors) { stage->_ReportErrors( pcpErrors, otherErrors, TfStringPrintf("Getting targets for relationship <%s>", GetPath().GetText())); } return !hasErrors; }