diff --git a/lib/usdUfe/ufe/Global.cpp b/lib/usdUfe/ufe/Global.cpp index c691292ff1..d3d85e1d68 100644 --- a/lib/usdUfe/ufe/Global.cpp +++ b/lib/usdUfe/ufe/Global.cpp @@ -75,6 +75,8 @@ Ufe::Rtid initialize( UsdUfe::setIsAttributeLockedFn(dccFunctions.isAttributeLockedFn); if (dccFunctions.saveStageLoadRulesFn) UsdUfe::setSaveStageLoadRulesFn(dccFunctions.saveStageLoadRulesFn); + if (dccFunctions.isRootChildFn) + UsdUfe::setIsRootChildFn(dccFunctions.isRootChildFn); // Create a default stages subject if none is provided. if (nullptr == ss) { diff --git a/lib/usdUfe/ufe/Global.h b/lib/usdUfe/ufe/Global.h index 73fd2bb381..d42b4f4f43 100644 --- a/lib/usdUfe/ufe/Global.h +++ b/lib/usdUfe/ufe/Global.h @@ -46,6 +46,7 @@ struct USDUFE_PUBLIC DCCFunctions // Optional: default values will be used if no function is supplied. IsAttributeLockedFn isAttributeLockedFn = nullptr; SaveStageLoadRulesFn saveStageLoadRulesFn = nullptr; + IsRootChildFn isRootChildFn = nullptr; }; /*! Ufe runtime handlers used to initialize the plugin. diff --git a/lib/usdUfe/ufe/Utils.cpp b/lib/usdUfe/ufe/Utils.cpp index 56cacf308b..f1588c3aee 100644 --- a/lib/usdUfe/ufe/Utils.cpp +++ b/lib/usdUfe/ufe/Utils.cpp @@ -90,6 +90,7 @@ UsdUfe::UfePathToPrimFn gUfePathToPrimFn = nullptr; UsdUfe::TimeAccessorFn gTimeAccessorFn = nullptr; UsdUfe::IsAttributeLockedFn gIsAttributeLockedFn = nullptr; UsdUfe::SaveStageLoadRulesFn gSaveStageLoadRulesFn = nullptr; +UsdUfe::IsRootChildFn gIsRootChildFn = nullptr; } // anonymous namespace @@ -231,6 +232,29 @@ void saveStageLoadRules(const PXR_NS::UsdStageRefPtr& stage) gSaveStageLoadRulesFn(stage); } +void setIsRootChildFn(IsRootChildFn fn) +{ + // This function is allowed to be null in which case, the default implementation + // is used (isRootChildDefault()). + gIsRootChildFn = fn; +} + +bool isRootChild(const Ufe::Path& path) +{ + return gIsRootChildFn ? gIsRootChildFn(path) : isRootChildDefault(path); +} + +bool isRootChildDefault(const Ufe::Path& path) +{ + // When called we make the assumption that we are given a valid + // path and we are only testing whether or not we are a root child. + auto segments = path.getSegments(); + if (segments.size() != 2) { + TF_RUNTIME_ERROR(kIllegalUFEPath, path.string().c_str()); + } + return (segments[1].size() == 1); +} + int ufePathToInstanceIndex(const Ufe::Path& path, UsdPrim* prim) { int instanceIndex = UsdImagingDelegate::ALL_INSTANCES; @@ -254,17 +278,6 @@ int ufePathToInstanceIndex(const Ufe::Path& path, UsdPrim* prim) return instanceIndex; } -bool isRootChild(const Ufe::Path& path) -{ - // When called we make the assumption that we are given a valid - // path and we are only testing whether or not we are a root child. - auto segments = path.getSegments(); - if (segments.size() != 2) { - TF_RUNTIME_ERROR(kIllegalUFEPath, path.string().c_str()); - } - return (segments[1].size() == 1); -} - std::string uniqueName(const TfToken::HashSet& existingNames, std::string srcName) { // Compiled regular expression to find a numerical suffix to a path component. diff --git a/lib/usdUfe/ufe/Utils.h b/lib/usdUfe/ufe/Utils.h index f656ceac47..eb0f856040 100644 --- a/lib/usdUfe/ufe/Utils.h +++ b/lib/usdUfe/ufe/Utils.h @@ -44,6 +44,7 @@ typedef PXR_NS::UsdPrim (*UfePathToPrimFn)(const Ufe::Path&); typedef PXR_NS::UsdTimeCode (*TimeAccessorFn)(const Ufe::Path&); typedef bool (*IsAttributeLockedFn)(const PXR_NS::UsdAttribute& attr, std::string* errMsg); typedef void (*SaveStageLoadRulesFn)(const PXR_NS::UsdStageRefPtr&); +typedef bool (*IsRootChildFn)(const Ufe::Path& path); //------------------------------------------------------------------------------ // Helper functions @@ -137,9 +138,22 @@ void saveStageLoadRules(const PXR_NS::UsdStageRefPtr& stage); USDUFE_PUBLIC int ufePathToInstanceIndex(const Ufe::Path& path, PXR_NS::UsdPrim* prim = nullptr); +//! Set the DCC specific "isRootChild" test function. +//! Use of this function is optional, if one is not supplied then +//! a default implementation of isRootChild is used.. +USDUFE_PUBLIC +void setIsRootChildFn(IsRootChildFn fn); + +//! Returns true if the path corresponds to an item at the root of a runtime. +//! Implementation can be set by the DCC. USDUFE_PUBLIC bool isRootChild(const Ufe::Path& path); +//! Default isRootChild() implementation. Assumes 2 segments. Will report a root child +//! if the second segment has a single component. +USDUFE_PUBLIC +bool isRootChildDefault(const Ufe::Path& path); + //! Split the source name into a base name and a numerical suffix (set to //! 1 if absent). Increment the numerical suffix until name is unique. USDUFE_PUBLIC