bool UsdProperty::IsAuthoredAt(const UsdEditTarget &editTarget) const { if (editTarget.IsValid()) { SdfPath mappedPath = editTarget.MapToSpecPath(GetPrimPath()); return !mappedPath.IsEmpty() && editTarget.GetLayer()->HasSpec( SdfAbstractDataSpecId(&mappedPath, &_PropName())); } return false; }
/* static */ UsdUISceneGraphPrimAPI UsdUISceneGraphPrimAPI::Apply(const UsdStagePtr &stage, const SdfPath &path) { // Ensure we have a valid stage, path and prim if (!stage) { TF_CODING_ERROR("Invalid stage"); return UsdUISceneGraphPrimAPI(); } if (path == SdfPath::AbsoluteRootPath()) { TF_CODING_ERROR("Cannot apply an api schema on the pseudoroot"); return UsdUISceneGraphPrimAPI(); } auto prim = stage->GetPrimAtPath(path); if (!prim) { TF_CODING_ERROR("Prim at <%s> does not exist.", path.GetText()); return UsdUISceneGraphPrimAPI(); } TfToken apiName("SceneGraphPrimAPI"); // Get the current listop at the edit target UsdEditTarget editTarget = stage->GetEditTarget(); SdfPrimSpecHandle primSpec = editTarget.GetPrimSpecForScenePath(path); SdfTokenListOp listOp = primSpec->GetInfo(UsdTokens->apiSchemas) .UncheckedGet<SdfTokenListOp>(); // Append our name to the prepend list, if it doesnt exist locally TfTokenVector prepends = listOp.GetPrependedItems(); if (std::find(prepends.begin(), prepends.end(), apiName) != prepends.end()) { return UsdUISceneGraphPrimAPI(); } SdfTokenListOp prependListOp; prepends.push_back(apiName); prependListOp.SetPrependedItems(prepends); auto result = listOp.ApplyOperations(prependListOp); if (!result) { TF_CODING_ERROR("Failed to prepend api name to current listop."); return UsdUISceneGraphPrimAPI(); } // Set the listop at the current edit target and return the API prim primSpec->SetInfo(UsdTokens->apiSchemas, VtValue(*result)); return UsdUISceneGraphPrimAPI(prim); }
void GusdPrimWrapper::updateTransformFromGTPrim( const GfMatrix4d &xform, UsdTimeCode time, bool force ) { UsdGeomImageable usdGeom = getUsdPrimForWrite(); UsdGeomXformable prim( usdGeom ); // Determine if we need to clear previous transformations from a stronger // opinion on the stage before authoring ours. UsdStagePtr stage = usdGeom.GetPrim().GetStage(); UsdEditTarget currEditTarget = stage->GetEditTarget(); // If the edit target does no mapping, it is most likely the session // layer which means it is in the local layer stack and can overlay // any xformOps. if ( !currEditTarget.GetMapFunction().IsNull() && !currEditTarget.GetMapFunction().IsIdentity() ) { bool reset; std::vector<UsdGeomXformOp> xformVec = prim.GetOrderedXformOps(&reset); // The xformOps attribute is static so we only check if we haven't // changed anything yet. In addition nothing needs to be cleared if it // was previously empty. if (m_lastXformSet.IsDefault() && (int)xformVec.size() > 0) { // Load the root layer for temp, stronger opinion changes. stage->GetRootLayer()->SetPermissionToSave(false); stage->SetEditTarget(stage->GetRootLayer()); UsdGeomXformable stagePrim( getUsdPrimForWrite() ); // Clear the xformOps on the stronger layer, so our weaker edit // target (with mapping across a reference) can write out clean, // new transforms. stagePrim.ClearXformOpOrder(); stage->SetEditTarget(currEditTarget); } } if( !prim ) return; // Try to avoid setting the transform when we can. // If force it true, always write the transform (used when writting per frame) bool setKnot = true; if( !force ) { // Has the transform has been set at least once if( !m_lastXformSet.IsDefault() ) { // Is the transform at this frame the same as the last frame if( isClose(xform,m_xformCache) ) { setKnot = false; m_lastXformCompared = time; } else { // If the transform has been held for more than one frame, // set a knot on the last frame if( m_lastXformCompared != m_lastXformSet ) { prim.MakeMatrixXform().Set( m_xformCache, m_lastXformCompared ); } } } else { // If the transform is an identity, don't set it if( isClose(xform,GfMatrix4d( 1.0 ))) { setKnot = false; m_lastXformCompared = time; } else { // If the transform was identity and now isn't, set a knot on the last frame if( !m_lastXformCompared.IsDefault() ) { prim.MakeMatrixXform().Set( GfMatrix4d(1.0), m_lastXformCompared ); } } } } if( setKnot ) { prim.MakeMatrixXform().Set( xform, time ); m_xformCache = xform; m_lastXformSet = time; m_lastXformCompared = time; } }
static bool _SetOrMergeOverOp(std::vector<int64_t> const &items, SdfListOpType op, UsdPrim const &prim) { SdfInt64ListOp proposed, current; UsdStagePtr stage = prim.GetStage(); UsdEditTarget editTarget = stage->GetEditTarget(); SdfPrimSpecHandle primSpec = editTarget.GetPrimSpecForScenePath(prim.GetPath()); if (primSpec){ VtValue existingOp = primSpec->GetInfo(UsdGeomTokens->inactiveIds); if (existingOp.IsHolding<SdfInt64ListOp>()){ current = existingOp.UncheckedGet<SdfInt64ListOp>(); } } proposed.SetItems(items, op); if (current.IsExplicit()){ std::vector<int64_t> explicitItems = current.GetExplicitItems(); proposed.ApplyOperations(&explicitItems); current.SetExplicitItems(explicitItems); } else { // We can't use ApplyOperations on an extant, non-explicit listOp // because the result is always flat and explicit. current.ComposeOperations(proposed, op); // ComposeOperations() is too narrow in functionality - it does not // consider that if we "remove over" an existing set of added items, // we need to additionally ensure the removed items get removed // from the added in current, since when applying ops, we first // remove, then add. Bug #139215 filed to track; when it gets fixed // we can remove this code! if (op == SdfListOpTypeDeleted){ std::vector<int64_t> addedItems = current.GetAddedItems(); if (!addedItems.empty()){ std::set<int64_t> toRemove(items.begin(), items.end()); std::vector<int64_t> newAdded; newAdded.reserve(addedItems.size()); for (auto elt : addedItems){ if (!toRemove.count(elt)) newAdded.push_back(elt); } if (newAdded.size() != addedItems.size()) current.SetAddedItems(newAdded); } } else if (op == SdfListOpTypeAdded){ std::vector<int64_t> deletedItems = current.GetDeletedItems(); if (!deletedItems.empty()){ std::set<int64_t> toAdd(items.begin(), items.end()); std::vector<int64_t> newDeleted; newDeleted.reserve(deletedItems.size()); for (auto elt : deletedItems){ if (!toAdd.count(elt)) newDeleted.push_back(elt); } if (newDeleted.size() != deletedItems.size()) current.SetDeletedItems(newDeleted); } } } return prim.SetMetadata(UsdGeomTokens->inactiveIds, current); }