static SdfPath _AppendNode(const SdfPath &path, const Sdf_PathNodeConstRefPtr &node) { switch (node->GetNodeType()) { case Sdf_PathNode::PrimNode: return path.AppendChild(node->GetName()); case Sdf_PathNode::PrimPropertyNode: return path.AppendProperty(node->GetName()); case Sdf_PathNode::PrimVariantSelectionNode: { const Sdf_PathNode::VariantSelectionType& selection = node->GetVariantSelection(); return path.AppendVariantSelection(selection.first.GetString(), selection.second.GetString()); } case Sdf_PathNode::TargetNode: return path.AppendTarget( node->GetTargetPath()); case Sdf_PathNode::RelationalAttributeNode: return path.AppendRelationalAttribute(node->GetName()); case Sdf_PathNode::MapperNode: return path.AppendMapper(node->GetTargetPath()); case Sdf_PathNode::MapperArgNode: return path.AppendMapperArg(node->GetName()); case Sdf_PathNode::ExpressionNode: return path.AppendExpression(); default: // CODE_COVERAGE_OFF // Should never get here. All reasonable cases are // handled above. TF_CODING_ERROR("Unexpected node type %i", node->GetNodeType()); return SdfPath::EmptyPath(); // CODE_COVERAGE_ON } }
SdfPath SdfPath::_ReplacePrefix(const SdfPath &oldPrefix, const SdfPath &newPrefix, bool fixTargetPaths) const { if (*this == oldPrefix) { // Base case: we've reached oldPrefix. return newPrefix; } if (GetPathElementCount() == 0) { // Empty paths have nothing to replace. return *this; } // If we've recursed above the oldPrefix, we can bail as long as there // are no target paths we need to fix. if (GetPathElementCount() <= oldPrefix.GetPathElementCount() && (!fixTargetPaths || !_pathNode->ContainsTargetPath())) { // We'll never see oldPrefix beyond here, so return. return *this; } // Recursively translate the parent. SdfPath parent = GetParentPath()._ReplacePrefix(oldPrefix, newPrefix, fixTargetPaths); // Translation of the parent may fail; it will have emitted an error. // Return here so we don't deref an invalid _pathNode below. if (parent.IsEmpty()) return SdfPath(); // Append the tail component. Use _AppendNode() except in these cases: // - For prims and properties, we construct child nodes directly // so as to not expand out ".." components and to avoid the cost // of unnecessarily re-validating identifiers. // - For embedded target paths, translate the target path. switch (_pathNode->GetNodeType()) { case Sdf_PathNode::PrimNode: return SdfPath(Sdf_PathNode::FindOrCreatePrim(parent._pathNode, _pathNode->GetName())); case Sdf_PathNode::PrimPropertyNode: return SdfPath(Sdf_PathNode::FindOrCreatePrimProperty( parent._pathNode, _pathNode->GetName())); case Sdf_PathNode::TargetNode: if (fixTargetPaths) { return parent.AppendTarget( _pathNode->GetTargetPath() ._ReplacePrefix(oldPrefix, newPrefix, fixTargetPaths)); } else { return _AppendNode(parent, _pathNode); } case Sdf_PathNode::MapperNode: if (fixTargetPaths) { return parent.AppendMapper( _pathNode->GetTargetPath() ._ReplacePrefix(oldPrefix, newPrefix, fixTargetPaths)); } else { return _AppendNode(parent, _pathNode); } default: return _AppendNode(parent, _pathNode); } }