bool UsdRelationship::ClearTargets(bool removeSpec) const { // NOTE! Do not insert any code that modifies scene description between the // changeblock and the call to _CreateSpec! Explanation: _CreateSpec calls // code that inspects the composition graph and then does some authoring. // We want that authoring to be inside the change block, but if any scene // description changes are made after the block is created but before we // call _CreateSpec, the composition structure may be invalidated. SdfChangeBlock block; SdfRelationshipSpecHandle relSpec = _CreateSpec(); if (!relSpec) return false; if (removeSpec){ SdfPrimSpecHandle owner = TfDynamic_cast<SdfPrimSpecHandle>(relSpec->GetOwner()); owner->RemoveProperty(relSpec); } else { relSpec->GetTargetPathList().ClearEdits(); } return true; }
bool UsdRelationship::SetTargets(const SdfPathVector& targets) const { SdfPathVector mappedPaths; mappedPaths.reserve(targets.size()); for (const SdfPath &target: targets) { std::string errMsg; mappedPaths.push_back(_GetTargetForAuthoring(target, &errMsg)); if (mappedPaths.back().IsEmpty()) { TF_CODING_ERROR("Cannot set target <%s> on relationship <%s>: %s", target.GetText(), GetPath().GetText(), errMsg.c_str()); return false; } } // NOTE! Do not insert any code that modifies scene description between the // changeblock and the call to _CreateSpec! Explanation: _CreateSpec calls // code that inspects the composition graph and then does some authoring. // We want that authoring to be inside the change block, but if any scene // description changes are made after the block is created but before we // call _CreateSpec, the composition structure may be invalidated. SdfChangeBlock block; SdfRelationshipSpecHandle relSpec = _CreateSpec(); if (!relSpec) return false; relSpec->GetTargetPathList().ClearEditsAndMakeExplicit(); for (const SdfPath &path: mappedPaths) { relSpec->GetTargetPathList().Add(path); } return true; }
bool UsdRelationship::RemoveTarget(const SdfPath& target) const { std::string errMsg; const SdfPath targetToAuthor = _GetTargetForAuthoring(target, &errMsg); if (targetToAuthor.IsEmpty()) { TF_CODING_ERROR("Cannot remove target <%s> from relationship <%s>: %s", target.GetText(), GetPath().GetText(), errMsg.c_str()); return false; } // NOTE! Do not insert any code that modifies scene description between the // changeblock and the call to _CreateSpec! Explanation: _CreateSpec calls // code that inspects the composition graph and then does some authoring. // We want that authoring to be inside the change block, but if any scene // description changes are made after the block is created but before we // call _CreateSpec, the composition structure may be invalidated. SdfChangeBlock block; SdfRelationshipSpecHandle relSpec = _CreateSpec(); if (!relSpec) return false; relSpec->GetTargetPathList().Remove(targetToAuthor); return true; }
bool PxrUsdKatana_AreRelTargetsFromBaseMaterial(const UsdRelationship &rel) { // Find the strongest opinion about the relationship targets. SdfRelationshipSpecHandle strongestRelSpec; SdfPropertySpecHandleVector propStack = rel.GetPropertyStack(); for (const SdfPropertySpecHandle &prop: propStack) { if (SdfRelationshipSpecHandle relSpec = TfDynamic_cast<SdfRelationshipSpecHandle>(prop)) { if (relSpec->HasTargetPathList()) { strongestRelSpec = relSpec; break; } } } // Find which prim node introduced that opinion. if (strongestRelSpec) { for(const PcpNodeRef &node: rel.GetPrim().GetPrimIndex().GetNodeRange()) { if (node.GetPath() == strongestRelSpec->GetPath().GetPrimPath() && node.GetLayerStack()->HasLayer(strongestRelSpec->GetLayer())) { return _NodeRepresentsLiveBaseMaterial(node); } } } return false; }
bool UsdRelationship::BlockTargets() const { // NOTE! Do not insert any code that modifies scene description between the // changeblock and the call to _CreateSpec! Explanation: _CreateSpec calls // code that inspects the composition graph and then does some authoring. // We want that authoring to be inside the change block, but if any scene // description changes are made after the block is created but before we // call _CreateSpec, the composition structure may be invalidated. SdfChangeBlock block; SdfRelationshipSpecHandle relSpec = _CreateSpec(); if (!relSpec) return false; relSpec->GetTargetPathList().ClearEditsAndMakeExplicit(); return true; }
SdfAttributeSpecHandle SdfAttributeSpec::_New( const SdfRelationshipSpecHandle& owner, const SdfPath& path, const std::string& name, const SdfValueTypeName& typeName, SdfVariability variability, bool custom) { if (not owner) { TF_CODING_ERROR("NULL owner"); return TfNullPtr; } if (not typeName) { TF_CODING_ERROR("Cannot create attribute spec <%s> with invalid type", owner->GetPath().AppendTarget(path). AppendProperty(TfToken(name)).GetText()); return TfNullPtr; } SdfChangeBlock block; // Determine the path of the relationship target SdfPath absPath = path.MakeAbsolutePath(owner->GetPath().GetPrimPath()); SdfPath targetPath = owner->GetPath().AppendTarget(absPath); // Check to make sure that the name is valid if (not Sdf_ChildrenUtils<Sdf_AttributeChildPolicy>::IsValidName(name)) { TF_CODING_ERROR( "Cannot create attribute on %s with invalid name: %s", targetPath.GetText(), name.c_str()); return TfNullPtr; } // Create the relationship target if it doesn't already exist. Note // that this does not automatically get added to the relationship's // target path list. SdfSpecHandle targetSpec = owner->_FindOrCreateTargetSpec(path); // AttributeSpecs are considered initially to have only required fields // only if they are not custom. bool hasOnlyRequiredFields = (not custom); // Create the relational attribute spec SdfPath attrPath = targetPath.AppendRelationalAttribute(TfToken(name)); if (not Sdf_ChildrenUtils<Sdf_AttributeChildPolicy>::CreateSpec( owner->GetLayer(), attrPath, SdfSpecTypeAttribute, hasOnlyRequiredFields)) { return TfNullPtr; } SdfAttributeSpecHandle spec = owner->GetLayer()->GetAttributeAtPath(attrPath); // Avoid expensive dormancy checks in the case of binary-backed data. SdfAttributeSpec *specPtr = get_pointer(spec); if (TF_VERIFY(specPtr)) { specPtr->SetField(SdfFieldKeys->Custom, custom); specPtr->SetField(SdfFieldKeys->TypeName, typeName.GetAsToken()); specPtr->SetField(SdfFieldKeys->Variability, variability); } return spec; }