From 1f87b7b93e908339771914d484b077eedf5ce25e Mon Sep 17 00:00:00 2001 From: stevelavietes Date: Wed, 27 Jul 2022 08:50:35 -0700 Subject: [PATCH] introduces UsdImagingLightAPIAdapter for UsdImagingStageSceneIndex - adds support for delivering multiple renderContext nodeIdentifier values within HdMaterialNodeSchema - adds fallback for HdSceneIndexAdapterSceneDelegate::GetLightParamValue to check against the light terminal node within the "material" data source - this is to handle legacy render delegate cases which expect to find light shader parameters within GetLightParamValue without compromising forward-looking use of material - allows UsdImagingDataSourceMaterial to answer for unauthored light param attributes (like intensity) to match expectations of legacy hdStorm render delegate - updates disk, distant, dome, plugin, rect and sphere light adapters to implement population-equivalent code for scene index pathway (GetImagingSubprimType) - STILL TODO: have UsdImagingLightAPIAdapter provide "light" data source child values for "filters", "lightLink", "shadowLink" and "lightFilterLink" (corresponding collections are already handled by built-in support for API schemas, yeah!) (Internal change: 2243381) (Internal change: 2243412) (Internal change: 2243439) --- pxr/imaging/hd/dataSourceLegacyPrim.cpp | 6 +- pxr/imaging/hd/materialNodeSchema.cpp | 30 ++- pxr/imaging/hd/materialNodeSchema.h | 24 ++- .../hd/sceneIndexAdapterSceneDelegate.cpp | 124 +++++++++-- pxr/usdImaging/usdImaging/CMakeLists.txt | 1 + .../usdImaging/dataSourceMaterial.cpp | 169 ++++++++++++++- .../usdImaging/dataSourceMaterial.h | 13 +- .../usdImaging/diskLightAdapter.cpp | 16 ++ pxr/usdImaging/usdImaging/diskLightAdapter.h | 12 ++ .../usdImaging/distantLightAdapter.cpp | 16 ++ .../usdImaging/distantLightAdapter.h | 12 ++ .../usdImaging/domeLightAdapter.cpp | 16 ++ pxr/usdImaging/usdImaging/domeLightAdapter.h | 12 ++ pxr/usdImaging/usdImaging/lightAPIAdapter.cpp | 195 ++++++++++++++++++ pxr/usdImaging/usdImaging/lightAPIAdapter.h | 53 +++++ pxr/usdImaging/usdImaging/plugInfo.json | 7 + .../usdImaging/pluginLightAdapter.cpp | 16 ++ .../usdImaging/pluginLightAdapter.h | 12 ++ .../usdImaging/rectLightAdapter.cpp | 16 ++ pxr/usdImaging/usdImaging/rectLightAdapter.h | 13 ++ .../usdImaging/sphereLightAdapter.cpp | 16 ++ .../usdImaging/sphereLightAdapter.h | 14 ++ 22 files changed, 761 insertions(+), 32 deletions(-) create mode 100644 pxr/usdImaging/usdImaging/lightAPIAdapter.cpp create mode 100644 pxr/usdImaging/usdImaging/lightAPIAdapter.h diff --git a/pxr/imaging/hd/dataSourceLegacyPrim.cpp b/pxr/imaging/hd/dataSourceLegacyPrim.cpp index 41843cc2da..3587b56d7c 100644 --- a/pxr/imaging/hd/dataSourceLegacyPrim.cpp +++ b/pxr/imaging/hd/dataSourceLegacyPrim.cpp @@ -2638,7 +2638,8 @@ _ConvertHdMaterialNetworkToHdDataSources( cNames.data(), cValues.data()), HdRetainedTypedSampledDataSource::New( - node.identifier))); + node.identifier), + nullptr /*renderContextNodeIdentifiers*/)); } terminalsValues.push_back( @@ -2699,7 +2700,8 @@ _ConvertSampleFilterNodeToHdDataSources( paramsValues.data()), HdRetainedContainerDataSource::New(),// SampleFilter has no connections HdRetainedTypedSampledDataSource::New( - hdNode.nodeTypeId)); + hdNode.nodeTypeId), + nullptr /*renderContextNodeIdentifiers*/); *result = HdSampleFilterSchema::BuildRetained(nodeDS); diff --git a/pxr/imaging/hd/materialNodeSchema.cpp b/pxr/imaging/hd/materialNodeSchema.cpp index b1fbffb613..1dfa6e265b 100644 --- a/pxr/imaging/hd/materialNodeSchema.cpp +++ b/pxr/imaging/hd/materialNodeSchema.cpp @@ -59,16 +59,24 @@ HdMaterialNodeSchema::GetNodeIdentifier() HdMaterialNodeSchemaTokens->nodeIdentifier); } +HdContainerDataSourceHandle +HdMaterialNodeSchema::GetRenderContextNodeIdentifiers() +{ + return _GetTypedDataSource( + HdMaterialNodeSchemaTokens->renderContextNodeIdentifiers); +} + /*static*/ HdContainerDataSourceHandle HdMaterialNodeSchema::BuildRetained( const HdContainerDataSourceHandle ¶meters, const HdContainerDataSourceHandle &inputConnections, - const HdTokenDataSourceHandle &nodeIdentifier + const HdTokenDataSourceHandle &nodeIdentifier, + const HdContainerDataSourceHandle &renderContextNodeIdentifiers ) { - TfToken names[3]; - HdDataSourceBaseHandle values[3]; + TfToken names[4]; + HdDataSourceBaseHandle values[4]; size_t count = 0; if (parameters) { @@ -86,6 +94,11 @@ HdMaterialNodeSchema::BuildRetained( values[count++] = nodeIdentifier; } + if (renderContextNodeIdentifiers) { + names[count] = HdMaterialNodeSchemaTokens->renderContextNodeIdentifiers; + values[count++] = renderContextNodeIdentifiers; + } + return HdRetainedContainerDataSource::New(count, names, values); } @@ -114,13 +127,22 @@ HdMaterialNodeSchema::Builder::SetNodeIdentifier( return *this; } +HdMaterialNodeSchema::Builder & +HdMaterialNodeSchema::Builder::SetRenderContextNodeIdentifiers( + const HdContainerDataSourceHandle &renderContextNodeIdentifiers) +{ + _renderContextNodeIdentifiers = renderContextNodeIdentifiers; + return *this; +} + HdContainerDataSourceHandle HdMaterialNodeSchema::Builder::Build() { return HdMaterialNodeSchema::BuildRetained( _parameters, _inputConnections, - _nodeIdentifier + _nodeIdentifier, + _renderContextNodeIdentifiers ); } diff --git a/pxr/imaging/hd/materialNodeSchema.h b/pxr/imaging/hd/materialNodeSchema.h index 7d66c5e11b..9e39d99241 100644 --- a/pxr/imaging/hd/materialNodeSchema.h +++ b/pxr/imaging/hd/materialNodeSchema.h @@ -40,6 +40,7 @@ PXR_NAMESPACE_OPEN_SCOPE (parameters) \ (inputConnections) \ (nodeIdentifier) \ + (renderContextNodeIdentifiers) \ TF_DECLARE_PUBLIC_TOKENS(HdMaterialNodeSchemaTokens, HD_API, HDMATERIALNODE_SCHEMA_TOKENS); @@ -58,9 +59,25 @@ class HdMaterialNodeSchema : public HdSchema HdContainerDataSourceHandle GetParameters(); HD_API HdContainerDataSourceHandle GetInputConnections(); + + // This identifies the shader the node represents. The + // renderContextNodeIdentifier container can store alternative values for + // this. A consumer which is interested in a specific render context + // should check for that token within renderContextNodeIdentifiers and + // fall back on this value in its absence. HD_API HdTokenDataSourceHandle GetNodeIdentifier(); + // A shading node can hold a nodeIdentifier value for multiple render + // contexts at once. This allows multiple renderer target representations + // to coexist in the same renderable scene. The contents of this + // container are alternate possible values for nodeIdentifier. A consumer + // which is interested in a specific render context should check for that + // token within this container and fall back on nodeIdentifier in its + // absence. + HD_API + HdContainerDataSourceHandle GetRenderContextNodeIdentifiers(); + // RETRIEVING AND CONSTRUCTING /// Builds a container data source which includes the provided child data @@ -73,7 +90,8 @@ class HdMaterialNodeSchema : public HdSchema BuildRetained( const HdContainerDataSourceHandle ¶meters, const HdContainerDataSourceHandle &inputConnections, - const HdTokenDataSourceHandle &nodeIdentifier + const HdTokenDataSourceHandle &nodeIdentifier, + const HdContainerDataSourceHandle &renderContextNodeIdentifiers ); /// \class HdMaterialNodeSchema::Builder @@ -94,6 +112,9 @@ class HdMaterialNodeSchema : public HdSchema HD_API Builder &SetNodeIdentifier( const HdTokenDataSourceHandle &nodeIdentifier); + HD_API + Builder &SetRenderContextNodeIdentifiers( + const HdContainerDataSourceHandle &renderContextNodeIdentifiers); /// Returns a container data source containing the members set thus far. HD_API @@ -103,6 +124,7 @@ class HdMaterialNodeSchema : public HdSchema HdContainerDataSourceHandle _parameters; HdContainerDataSourceHandle _inputConnections; HdTokenDataSourceHandle _nodeIdentifier; + HdContainerDataSourceHandle _renderContextNodeIdentifiers; }; }; diff --git a/pxr/imaging/hd/sceneIndexAdapterSceneDelegate.cpp b/pxr/imaging/hd/sceneIndexAdapterSceneDelegate.cpp index 6b003c1686..ab51a3ab90 100644 --- a/pxr/imaging/hd/sceneIndexAdapterSceneDelegate.cpp +++ b/pxr/imaging/hd/sceneIndexAdapterSceneDelegate.cpp @@ -895,6 +895,7 @@ void _Walk( const SdfPath & nodePath, const HdContainerDataSourceHandle & nodesDS, + const TfTokenVector &renderContexts, std::unordered_set * visitedSet, HdMaterialNetwork * netHd) { @@ -914,8 +915,34 @@ _Walk( if (!nodeSchema.IsDefined()) { return; } - - const TfToken nodeId = nodeSchema.GetNodeIdentifier()->GetTypedValue(0); + + TfToken nodeId; + if (HdTokenDataSourceHandle idDs = nodeSchema.GetNodeIdentifier()) { + nodeId = idDs->GetTypedValue(0); + } + + // check for render-specific contexts + if (!renderContexts.empty()) { + if (HdContainerDataSourceHandle idsDs = + nodeSchema.GetRenderContextNodeIdentifiers()) { + for (const TfToken &name : renderContexts) { + + if (name.IsEmpty() && !nodeId.IsEmpty()) { + break; + } + if (HdTokenDataSourceHandle ds = HdTokenDataSource::Cast( + idsDs->Get(name))) { + + const TfToken v = ds->GetTypedValue(0); + if (!v.IsEmpty()) { + nodeId = v; + break; + } + } + } + } + } + HdContainerDataSourceHandle connsDS = nodeSchema.GetInputConnections(); HdContainerDataSourceHandle paramsDS = nodeSchema.GetParameters(); @@ -941,7 +968,8 @@ _Walk( TfToken p = connSchema.GetUpstreamNodePath()->GetTypedValue(0); TfToken n = connSchema.GetUpstreamNodeOutputName()->GetTypedValue(0); - _Walk(SdfPath(p.GetString()), nodesDS, visitedSet, netHd); + _Walk(SdfPath(p.GetString()), nodesDS, renderContexts, + visitedSet, netHd); HdMaterialRelationship r; r.inputId = SdfPath(p.GetString()); @@ -1041,15 +1069,20 @@ HdSceneIndexAdapterSceneDelegate::GetMaterialResource(SdfPath const & id) SdfPath path(pathTk.GetString()); matHd.terminals.push_back(path); + + TfTokenVector renderContexts = + GetRenderIndex().GetRenderDelegate()->GetMaterialRenderContexts(); + + // Continue walking the network HdMaterialNetwork & netHd = matHd.map[name]; - _Walk(path, nodesDS, &visitedNodes, &netHd); + _Walk(path, nodesDS, renderContexts, &visitedNodes, &netHd); // see "includeDisconnectedNodes" above if (includeDisconnectedNodes && nodesDS) { for (const TfToken &nodeName : nodesDS->GetNames()) { _Walk(SdfPath(nodeName.GetString()), - nodesDS, &visitedNodes, &netHd); + nodesDS, renderContexts, &visitedNodes, &netHd); } } } @@ -1120,6 +1153,61 @@ HdSceneIndexAdapterSceneDelegate::GetCameraParamValue( } } +// Render delegates which retrieve light params (such as "intensity") via +// GetLightParamValue rather than from a light's material resource need to be +// mapped back to the "material" data source for cases when the data is not +// provided by a legacy scene delegate. Because filtering scene indices may +// be modifying the "material" data source value, this mapping can happen only +// when adapting to legacy render delegates. +static +VtValue +_GetLightParamValueFromMaterial( + const HdContainerDataSourceHandle &primDataSource, + TfToken const ¶mName) +{ + + // these appear with "light" data source but are not expected to be within + // a light's shader within a material data source + if (paramName == HdTokens->filters + || paramName == HdTokens->lightLink + || paramName == HdTokens->shadowLink + || paramName == HdTokens->lightFilterLink) { + return VtValue(); + } + + if (auto mat = HdMaterialSchema::GetFromParent(primDataSource)) { + HdMaterialNetworkSchema network(mat.GetMaterialNetwork()); + if (HdContainerDataSourceHandle terminals = network.GetTerminals()) { + if (HdMaterialConnectionSchema connection = + HdMaterialConnectionSchema( + HdContainerDataSource::Cast( + terminals->Get(HdLightSchemaTokens->light)))) { + if (HdTokenDataSourceHandle nodeNameDs = + connection.GetUpstreamNodePath()) { + if (HdContainerDataSourceHandle nodes = + network.GetNodes()) { + if (HdContainerDataSourceHandle params = + HdMaterialNodeSchema( + HdContainerDataSource::Cast( + nodes->Get( + nodeNameDs->GetTypedValue(0.0f))) + ).GetParameters()) { + + if (auto param = HdSampledDataSource::Cast( + params->Get(paramName))) { + + return param->GetValue(0.0f); + } + } + } + } + } + } + } + + return VtValue(); +} + VtValue HdSceneIndexAdapterSceneDelegate::GetLightParamValue( SdfPath const &id, TfToken const ¶mName) @@ -1131,24 +1219,28 @@ HdSceneIndexAdapterSceneDelegate::GetLightParamValue( return VtValue(); } + // Prioritize retrieving light parameters from the material and fallback + // on "light" data source. + VtValue result = _GetLightParamValueFromMaterial(prim.dataSource, paramName); + + if (!result.IsEmpty()) { + return result; + } + HdContainerDataSourceHandle light = HdContainerDataSource::Cast( prim.dataSource->Get(HdLightSchemaTokens->light)); - if (!light) { - return VtValue(); - } - - HdSampledDataSourceHandle valueDs = - HdSampledDataSource::Cast( - light->Get(paramName)); - if (!valueDs) { - return VtValue(); + if (light) { + HdSampledDataSourceHandle valueDs = HdSampledDataSource::Cast( + light->Get(paramName)); + if (valueDs) { + result = valueDs->GetValue(0); + } } - return valueDs->GetValue(0); + return result; } - static VtValue _GetRenderSettings(HdSceneIndexPrim prim, TfToken const &key) { diff --git a/pxr/usdImaging/usdImaging/CMakeLists.txt b/pxr/usdImaging/usdImaging/CMakeLists.txt index 742760d81a..0df8f8f218 100644 --- a/pxr/usdImaging/usdImaging/CMakeLists.txt +++ b/pxr/usdImaging/usdImaging/CMakeLists.txt @@ -68,6 +68,7 @@ pxr_library(usdImaging implicitSurfaceMeshUtils instanceAdapter lightAdapter + lightAPIAdapter lightFilterAdapter materialAdapter materialBindingAPIAdapter diff --git a/pxr/usdImaging/usdImaging/dataSourceMaterial.cpp b/pxr/usdImaging/usdImaging/dataSourceMaterial.cpp index f9861439f2..e6c5fde592 100644 --- a/pxr/usdImaging/usdImaging/dataSourceMaterial.cpp +++ b/pxr/usdImaging/usdImaging/dataSourceMaterial.cpp @@ -25,8 +25,12 @@ #include "pxr/usdImaging/usdImaging/dataSourceAttribute.h" +#include "pxr/usd/usdLux/lightAPI.h" +#include "pxr/usd/usdLux/lightFilter.h" + #include "pxr/usd/usdShade/material.h" #include "pxr/usd/usdShade/materialBindingAPI.h" +#include "pxr/usd/usdShade/nodeDefAPI.h" #include "pxr/imaging/hd/retainedDataSource.h" #include "pxr/imaging/hd/tokens.h" @@ -82,6 +86,17 @@ class _UsdImagingDataSourceShadingNodeParameters : public HdContainerDataSource return UsdImagingDataSourceAttributeNew(attr, _stageGlobals); } + // fallback case for requested but unauthored inputs on lights or + // light filters -- which will not return a value for + // GetValueProducingAttribute but can still provide an attr + if (_shaderNode.GetPrim().HasAPI() + || _shaderNode.GetPrim().IsA()) { + attr = input.GetAttr(); + if (attr) { + return UsdImagingDataSourceAttributeNew(attr, _stageGlobals); + } + } + return nullptr; } @@ -162,6 +177,61 @@ class _UsdImagingDataSourceShadingNodeInputs : public HdContainerDataSource const UsdImagingDataSourceStageGlobals &_stageGlobals; }; +template +class _UsdImagingDataSourceRenderContextIdentifiers + : public HdContainerDataSource +{ +public: + HD_DECLARE_DATASOURCE(_UsdImagingDataSourceRenderContextIdentifiers); + + bool Has(const TfToken &name) override + { + return bool(_t.GetShaderIdAttrForRenderContext(name)); + } + + TfTokenVector GetNames() override + { + TfTokenVector result; + + for (const TfToken &propName : _t.GetPrim().GetPropertyNames()) { + const std::string &tokenStr = propName.GetString(); + std::size_t firstDelimIndex = tokenStr.find(':'); + if (firstDelimIndex == std::string::npos) { + continue; + } + + if (tokenStr.substr(firstDelimIndex + 1) != + UsdLuxTokens->lightShaderId.GetString()) { + continue; + } + + result.push_back(TfToken(tokenStr.substr(0, firstDelimIndex))); + } + + return result; + } + + HdDataSourceBaseHandle Get(const TfToken &name) override + { + if (UsdAttribute attr = _t.GetShaderIdAttrForRenderContext(name)) { + TfToken shaderId; + if (attr.Get(&shaderId)) { + return HdRetainedTypedSampledDataSource::New(shaderId); + } + } + + return nullptr; + } + +private: + + _UsdImagingDataSourceRenderContextIdentifiers( + const T &t) + : _t(t){} + + UsdLuxLightAPI _t; +}; + class _UsdImagingDataSourceShadingNode : public HdContainerDataSource { @@ -186,10 +256,40 @@ class _UsdImagingDataSourceShadingNode : public HdContainerDataSource { if (name == HdMaterialNodeSchemaTokens->nodeIdentifier) { TfToken nodeId; + + // the default identifier + + UsdShadeNodeDefAPI nodeDef(_shaderNode.GetPrim()); + if (nodeDef) { + nodeDef.GetShaderId(&nodeId); + } else if (UsdLuxLightFilter lightFilter = + UsdLuxLightFilter(_shaderNode.GetPrim())) { + nodeId = lightFilter.GetShaderId({}); + + } else if (UsdLuxLightAPI light = + UsdLuxLightAPI(_shaderNode.GetPrim())) { + nodeId = light.GetShaderId({}); + } + _shaderNode.GetShaderId(&nodeId); return HdRetainedTypedSampledDataSource::New(nodeId); } + if (name == HdMaterialNodeSchemaTokens->renderContextNodeIdentifiers) { + + if (UsdLuxLightAPI light = + UsdLuxLightAPI(_shaderNode.GetPrim())) { + return _UsdImagingDataSourceRenderContextIdentifiers< + UsdLuxLightAPI>::New(light); + } else if (UsdLuxLightFilter lightFilter = + UsdLuxLightFilter(_shaderNode.GetPrim())) { + return _UsdImagingDataSourceRenderContextIdentifiers< + UsdLuxLightFilter>::New(lightFilter); + } + + return nullptr; + } + if (name == HdMaterialNodeSchemaTokens->parameters) { return _UsdImagingDataSourceShadingNodeParameters::New( _shaderNode, _stageGlobals); @@ -220,9 +320,11 @@ class _UsdImagingDataSourceShadingNode : public HdContainerDataSource UsdImagingDataSourceMaterial::UsdImagingDataSourceMaterial( UsdPrim usdPrim, - const UsdImagingDataSourceStageGlobals & stageGlobals) + const UsdImagingDataSourceStageGlobals & stageGlobals, + const TfToken &fixedTerminalName) : _usdPrim(usdPrim) , _stageGlobals(stageGlobals) +, _fixedTerminalName(fixedTerminalName) { } @@ -264,7 +366,7 @@ using _TokenDataSourceMap = static void _WalkGraph( - UsdShadeShader const &shadeNode, + UsdShadeConnectableAPI const &shadeNode, _TokenDataSourceMap *outputNodes, const UsdImagingDataSourceStageGlobals &stageGlobals) { @@ -298,7 +400,7 @@ _WalkGraph( for (const UsdAttribute &attr : attrs) { _WalkGraph( - UsdShadeShader(attr.GetPrim()), + UsdShadeConnectableAPI(attr.GetPrim()), outputNodes, stageGlobals); } @@ -310,10 +412,54 @@ _WalkGraph( outputNodes->insert({nodeName, nodeValue}); } +static +HdDataSourceBaseHandle +_BuildNetwork( + UsdShadeConnectableAPI const &terminalNode, + const TfToken &terminalName, + UsdImagingDataSourceStageGlobals const &stageGlobals, + TfToken const& context) +{ + + _TokenDataSourceMap nodeDataSources; + _WalkGraph(terminalNode, + &nodeDataSources, + stageGlobals); + + TfTokenVector nodeNames; + std::vector nodeValues; + nodeNames.reserve(nodeDataSources.size()); + nodeValues.reserve(nodeDataSources.size()); + for (const auto &tokenDsPair : nodeDataSources) { + nodeNames.push_back(tokenDsPair.first); + nodeValues.push_back(tokenDsPair.second); + } + + + HdContainerDataSourceHandle terminalsDs = + HdRetainedContainerDataSource::New( + terminalName, + HdMaterialConnectionSchema::BuildRetained( + HdRetainedTypedSampledDataSource::New( + TfToken(terminalNode.GetPrim().GetPath().GetToken())), + HdRetainedTypedSampledDataSource::New( + terminalName))); + + HdContainerDataSourceHandle nodesDs = + HdRetainedContainerDataSource::New( + nodeNames.size(), + nodeNames.data(), + nodeValues.data()); + + return HdMaterialNetworkSchema::BuildRetained( + nodesDs, + terminalsDs); +} + static HdDataSourceBaseHandle _BuildMaterial( - UsdShadeMaterial const &usdMat, + UsdShadeNodeGraph const &usdMat, UsdImagingDataSourceStageGlobals const &stageGlobals, TfToken const& context) { @@ -333,8 +479,7 @@ _BuildMaterial( continue; } - UsdShadeShader upstreamShader = - UsdShadeShader(sourceInfo.source.GetPrim()); + UsdShadeConnectableAPI upstreamShader(sourceInfo.source.GetPrim()); _WalkGraph(upstreamShader, &nodeDataSources, @@ -392,8 +537,16 @@ UsdImagingDataSourceMaterial::Get(const TfToken &name) return it->second; } - HdDataSourceBaseHandle networkDs = _BuildMaterial( - UsdShadeMaterial(_usdPrim), _stageGlobals, name); + HdDataSourceBaseHandle networkDs; + + if (_fixedTerminalName.IsEmpty()) { + networkDs = _BuildMaterial( + UsdShadeNodeGraph(_usdPrim), _stageGlobals, name); + } else { + networkDs = _BuildNetwork(UsdShadeConnectableAPI(_usdPrim), + _fixedTerminalName, _stageGlobals, name); + } + _networks[name] = networkDs; return networkDs; diff --git a/pxr/usdImaging/usdImaging/dataSourceMaterial.h b/pxr/usdImaging/usdImaging/dataSourceMaterial.h index affdb8ef39..618dff1752 100644 --- a/pxr/usdImaging/usdImaging/dataSourceMaterial.h +++ b/pxr/usdImaging/usdImaging/dataSourceMaterial.h @@ -31,6 +31,8 @@ #include "pxr/usdImaging/usdImaging/dataSourcePrim.h" #include "pxr/usdImaging/usdImaging/dataSourceStageGlobals.h" +#include "pxr/usd/usdShade/connectableAPI.h" + #include PXR_NAMESPACE_OPEN_SCOPE @@ -53,9 +55,16 @@ class UsdImagingDataSourceMaterial : public HdContainerDataSource ~UsdImagingDataSourceMaterial(); private: + + /// If \p fixedTerminalName is specified, the provided \p usdPrim will be + /// treated as the terminal shader node in the graph rather than as a + /// material (with relationships to the prims serving as terminal shader + /// nodes). This is relevant for light and light filter cases. UsdImagingDataSourceMaterial( UsdPrim usdPrim, - const UsdImagingDataSourceStageGlobals &stageGlobals); + const UsdImagingDataSourceStageGlobals &stageGlobals, + const TfToken &fixedTerminalName = TfToken() + ); private: @@ -67,6 +76,8 @@ class UsdImagingDataSourceMaterial : public HdContainerDataSource using _ContextMap = tbb::concurrent_unordered_map< TfToken, HdDataSourceBaseHandle, TfToken::HashFunctor>; + + TfToken _fixedTerminalName; _ContextMap _networks; }; diff --git a/pxr/usdImaging/usdImaging/diskLightAdapter.cpp b/pxr/usdImaging/usdImaging/diskLightAdapter.cpp index b7cc6de07f..8c1b21871d 100644 --- a/pxr/usdImaging/usdImaging/diskLightAdapter.cpp +++ b/pxr/usdImaging/usdImaging/diskLightAdapter.cpp @@ -42,6 +42,22 @@ UsdImagingDiskLightAdapter::~UsdImagingDiskLightAdapter() { } +TfTokenVector +UsdImagingDiskLightAdapter::GetImagingSubprims() +{ + return { TfToken() }; +} + +TfToken +UsdImagingDiskLightAdapter::GetImagingSubprimType(TfToken const& subprim) +{ + if (subprim.IsEmpty()) { + return HdPrimTypeTokens->diskLight; + } + + return TfToken(); +} + bool UsdImagingDiskLightAdapter::IsSupported(UsdImagingIndexProxy const* index) const { diff --git a/pxr/usdImaging/usdImaging/diskLightAdapter.h b/pxr/usdImaging/usdImaging/diskLightAdapter.h index a002f74e2b..f68a1bbf3e 100644 --- a/pxr/usdImaging/usdImaging/diskLightAdapter.h +++ b/pxr/usdImaging/usdImaging/diskLightAdapter.h @@ -50,6 +50,18 @@ class UsdImagingDiskLightAdapter : public UsdImagingLightAdapter { USDIMAGING_API virtual ~UsdImagingDiskLightAdapter(); + // ---------------------------------------------------------------------- // + /// \name Scene Index Support + // ---------------------------------------------------------------------- // + + USDIMAGING_API + TfTokenVector GetImagingSubprims() override; + + USDIMAGING_API + TfToken GetImagingSubprimType(TfToken const& subprim) override; + + // ---------------------------------------------------------------------- // + USDIMAGING_API virtual SdfPath Populate(UsdPrim const& prim, UsdImagingIndexProxy* index, diff --git a/pxr/usdImaging/usdImaging/distantLightAdapter.cpp b/pxr/usdImaging/usdImaging/distantLightAdapter.cpp index 02aacafa0e..fcba06244b 100644 --- a/pxr/usdImaging/usdImaging/distantLightAdapter.cpp +++ b/pxr/usdImaging/usdImaging/distantLightAdapter.cpp @@ -42,6 +42,22 @@ UsdImagingDistantLightAdapter::~UsdImagingDistantLightAdapter() { } +TfTokenVector +UsdImagingDistantLightAdapter::GetImagingSubprims() +{ + return { TfToken() }; +} + +TfToken +UsdImagingDistantLightAdapter::GetImagingSubprimType(TfToken const& subprim) +{ + if (subprim.IsEmpty()) { + return HdPrimTypeTokens->distantLight; + } + + return TfToken(); +} + bool UsdImagingDistantLightAdapter::IsSupported(UsdImagingIndexProxy const* index) const { diff --git a/pxr/usdImaging/usdImaging/distantLightAdapter.h b/pxr/usdImaging/usdImaging/distantLightAdapter.h index 0b4db632d9..b9f2022f7c 100644 --- a/pxr/usdImaging/usdImaging/distantLightAdapter.h +++ b/pxr/usdImaging/usdImaging/distantLightAdapter.h @@ -50,6 +50,18 @@ class UsdImagingDistantLightAdapter : public UsdImagingLightAdapter { USDIMAGING_API virtual ~UsdImagingDistantLightAdapter(); + // ---------------------------------------------------------------------- // + /// \name Scene Index Support + // ---------------------------------------------------------------------- // + + USDIMAGING_API + TfTokenVector GetImagingSubprims() override; + + USDIMAGING_API + TfToken GetImagingSubprimType(TfToken const& subprim) override; + + // ---------------------------------------------------------------------- // + USDIMAGING_API virtual SdfPath Populate(UsdPrim const& prim, UsdImagingIndexProxy* index, diff --git a/pxr/usdImaging/usdImaging/domeLightAdapter.cpp b/pxr/usdImaging/usdImaging/domeLightAdapter.cpp index 6ebcd3506e..6f1858361d 100644 --- a/pxr/usdImaging/usdImaging/domeLightAdapter.cpp +++ b/pxr/usdImaging/usdImaging/domeLightAdapter.cpp @@ -42,6 +42,22 @@ UsdImagingDomeLightAdapter::~UsdImagingDomeLightAdapter() { } +TfTokenVector +UsdImagingDomeLightAdapter::GetImagingSubprims() +{ + return { TfToken() }; +} + +TfToken +UsdImagingDomeLightAdapter::GetImagingSubprimType(TfToken const& subprim) +{ + if (subprim.IsEmpty()) { + return HdPrimTypeTokens->domeLight; + } + + return TfToken(); +} + bool UsdImagingDomeLightAdapter::IsSupported(UsdImagingIndexProxy const* index) const { diff --git a/pxr/usdImaging/usdImaging/domeLightAdapter.h b/pxr/usdImaging/usdImaging/domeLightAdapter.h index 06c18d8dde..158bbcfd23 100644 --- a/pxr/usdImaging/usdImaging/domeLightAdapter.h +++ b/pxr/usdImaging/usdImaging/domeLightAdapter.h @@ -50,6 +50,18 @@ class UsdImagingDomeLightAdapter : public UsdImagingLightAdapter { USDIMAGING_API virtual ~UsdImagingDomeLightAdapter(); + // ---------------------------------------------------------------------- // + /// \name Scene Index Support + // ---------------------------------------------------------------------- // + + USDIMAGING_API + TfTokenVector GetImagingSubprims() override; + + USDIMAGING_API + TfToken GetImagingSubprimType(TfToken const& subprim) override; + + // ---------------------------------------------------------------------- // + USDIMAGING_API virtual SdfPath Populate(UsdPrim const& prim, UsdImagingIndexProxy* index, diff --git a/pxr/usdImaging/usdImaging/lightAPIAdapter.cpp b/pxr/usdImaging/usdImaging/lightAPIAdapter.cpp new file mode 100644 index 0000000000..8fad2db303 --- /dev/null +++ b/pxr/usdImaging/usdImaging/lightAPIAdapter.cpp @@ -0,0 +1,195 @@ +// +// Copyright 2022 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +#include "pxr/usdImaging/usdImaging/lightAPIAdapter.h" + +#include "pxr/usdImaging/usdImaging/dataSourceMaterial.h" + +#include "pxr/usd/usdLux/lightAPI.h" + +#include "pxr/imaging/hd/lightSchema.h" +#include "pxr/imaging/hd/materialSchema.h" +#include "pxr/imaging/hd/retainedDataSource.h" +#include "pxr/imaging/hd/tokens.h" + +#include "pxr/base/tf/stringUtils.h" + +PXR_NAMESPACE_OPEN_SCOPE + +TF_REGISTRY_FUNCTION(TfType) +{ + typedef UsdImagingLightAPIAdapter Adapter; + TfType t = TfType::Define >(); + t.SetFactory< UsdImagingAPISchemaAdapterFactory >(); +} + +namespace +{ + +class _LightDataSource : public HdContainerDataSource +{ +public: + HD_DECLARE_DATASOURCE(_LightDataSource); + + + bool + Has(const TfToken & name) override + { + for (const TfToken &n : GetNames()) { + if (name == n) { + return true; + } + } + return false; + } + + TfTokenVector + GetNames() override + { + static const TfTokenVector names = { + HdTokens->filters, + HdTokens->lightLink, + HdTokens->shadowLink, + //HdTokens->lightFilterLink, + }; + + return names; + } + + HdDataSourceBaseHandle + Get(const TfToken &name) override + { + if (name == HdTokens->filters) { + SdfPathVector filterPaths; + _lightApi.GetFiltersRel().GetForwardedTargets(&filterPaths); + return HdCreateTypedRetainedDataSource(VtValue(filterPaths)); + } else if (name == HdTokens->lightLink) { + UsdCollectionAPI c = _lightApi.GetLightLinkCollectionAPI(); + if (c.HasNoIncludedPaths()) { + return nullptr; + } + + // NOTE: The value here corresponds to the "category" name + // generated from our linking collection. For USD lights, + // that will be the full property path to the linking + // collection. + return HdRetainedTypedSampledDataSource::New( + c.GetCollectionPath().GetToken()); + } else if (name == HdTokens->shadowLink) { + UsdCollectionAPI c = _lightApi.GetShadowLinkCollectionAPI(); + if (c.HasNoIncludedPaths()) { + return nullptr; + } + + // NOTE: The value here corresponds to the "category" name + // generated from our linking collection. For USD lights, + // that will be the full property path to the linking + // collection. + return HdRetainedTypedSampledDataSource::New( + c.GetCollectionPath().GetToken()); + } + return nullptr; + } + +private: + + _LightDataSource(const UsdLuxLightAPI &lightApi) + : _lightApi(lightApi) + {} + + UsdLuxLightAPI _lightApi; +}; + +} // namespace anonymous + +HdContainerDataSourceHandle +UsdImagingLightAPIAdapter::GetImagingSubprimData( + TfToken const& subprim, + UsdPrim const& prim, + TfToken const& appliedInstanceName, + const UsdImagingDataSourceStageGlobals &stageGlobals) +{ + if (!subprim.IsEmpty() || !appliedInstanceName.IsEmpty()) { + return nullptr; + } + + if (subprim.IsEmpty()) { + return HdRetainedContainerDataSource::New( + HdPrimTypeTokens->material, + UsdImagingDataSourceMaterial::New( + prim, + stageGlobals, + HdMaterialTerminalTokens->light), + HdLightSchemaTokens->light, + _LightDataSource::New(UsdLuxLightAPI(prim))); + } + + return nullptr; +} + + +HdDataSourceLocatorSet +UsdImagingLightAPIAdapter::InvalidateImagingSubprim( + TfToken const& subprim, + TfToken const& appliedInstanceName, + TfTokenVector const& properties) +{ + if (!subprim.IsEmpty() || !appliedInstanceName.IsEmpty()) { + return HdDataSourceLocatorSet(); + } + + bool dirtiedMaterial = false; + bool dirtiedLight = false; + + HdDataSourceLocatorSet result; + for (const TfToken &propertyName : properties) { + if (!dirtiedMaterial + && TfStringStartsWith(propertyName.GetString(), "inputs:")) { + dirtiedMaterial = true; + // NOTE: since we don't have access to the prim itself and our + // light terminal is currently named for the USD path, + // we cannot be specific to the individual parameter. + // TODO: Consider whether we want to make the terminal node + // in the material network have a fixed name for the + // light case so that we could. + result.insert(HdMaterialSchema::GetDefaultLocator()); + } + + // NOTE: Having to make assumptions regarding relevant linking + // parameters as the relevant USD schemas don't offer static + // functions for name comparison without access to the prim + // instance. Let's assume collections defined here are linking + // related. + if (!dirtiedLight + && UsdCollectionAPI::CanContainPropertyName(propertyName)){ + dirtiedLight = true; + result.insert(HdLightSchema::GetDefaultLocator()); + } + } + + // TODO: contents of light data source + + return result; +} + +PXR_NAMESPACE_CLOSE_SCOPE \ No newline at end of file diff --git a/pxr/usdImaging/usdImaging/lightAPIAdapter.h b/pxr/usdImaging/usdImaging/lightAPIAdapter.h new file mode 100644 index 0000000000..5a68d270f6 --- /dev/null +++ b/pxr/usdImaging/usdImaging/lightAPIAdapter.h @@ -0,0 +1,53 @@ +// +// Copyright 2022 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +#ifndef PXR_USD_IMAGING_USD_IMAGING_LIGHT_API_ADAPTER_H +#define PXR_USD_IMAGING_USD_IMAGING_LIGHT_API_ADAPTER_H + +#include "pxr/usdImaging/usdImaging/apiSchemaAdapter.h" + +PXR_NAMESPACE_OPEN_SCOPE + +class UsdImagingLightAPIAdapter : public UsdImagingAPISchemaAdapter +{ +public: + + using BaseAdapter = UsdImagingAPISchemaAdapter; + + USDIMAGING_API + HdContainerDataSourceHandle GetImagingSubprimData( + TfToken const& subprim, + UsdPrim const& prim, + TfToken const& appliedInstanceName, + const UsdImagingDataSourceStageGlobals &stageGlobals) override; + + USDIMAGING_API + HdDataSourceLocatorSet InvalidateImagingSubprim( + TfToken const& subprim, + TfToken const& appliedInstanceName, + TfTokenVector const& properties) override; +}; + +PXR_NAMESPACE_CLOSE_SCOPE + +#endif \ No newline at end of file diff --git a/pxr/usdImaging/usdImaging/plugInfo.json b/pxr/usdImaging/usdImaging/plugInfo.json index 0f41ad8a3e..f5ffc25d15 100644 --- a/pxr/usdImaging/usdImaging/plugInfo.json +++ b/pxr/usdImaging/usdImaging/plugInfo.json @@ -179,6 +179,13 @@ "primTypeName": "LightAPI", "includeDerivedPrimTypes" : true }, + "UsdImagingLightAPIAdapter": { + "bases": [ + "UsdImagingAPISchemaAdapter" + ], + "isInternal": true, + "apiSchemaName": "LightAPI" + }, "UsdImagingLightFilterAdapter": { "bases": [ "UsdImagingPrimAdapter" diff --git a/pxr/usdImaging/usdImaging/pluginLightAdapter.cpp b/pxr/usdImaging/usdImaging/pluginLightAdapter.cpp index 76fc43d0d4..49376e6c13 100644 --- a/pxr/usdImaging/usdImaging/pluginLightAdapter.cpp +++ b/pxr/usdImaging/usdImaging/pluginLightAdapter.cpp @@ -42,6 +42,22 @@ UsdImagingPluginLightAdapter::~UsdImagingPluginLightAdapter() { } +TfTokenVector +UsdImagingPluginLightAdapter::GetImagingSubprims() +{ + return { TfToken() }; +} + +TfToken +UsdImagingPluginLightAdapter::GetImagingSubprimType(TfToken const& subprim) +{ + if (subprim.IsEmpty()) { + return HdPrimTypeTokens->pluginLight; + } + + return TfToken(); +} + bool UsdImagingPluginLightAdapter::IsSupported( UsdImagingIndexProxy const* index) const diff --git a/pxr/usdImaging/usdImaging/pluginLightAdapter.h b/pxr/usdImaging/usdImaging/pluginLightAdapter.h index 263a344f48..c688d53064 100644 --- a/pxr/usdImaging/usdImaging/pluginLightAdapter.h +++ b/pxr/usdImaging/usdImaging/pluginLightAdapter.h @@ -50,6 +50,18 @@ class UsdImagingPluginLightAdapter : public UsdImagingLightAdapter { USDIMAGING_API virtual ~UsdImagingPluginLightAdapter(); + // ---------------------------------------------------------------------- // + /// \name Scene Index Support + // ---------------------------------------------------------------------- // + + USDIMAGING_API + TfTokenVector GetImagingSubprims() override; + + USDIMAGING_API + TfToken GetImagingSubprimType(TfToken const& subprim) override; + + // ---------------------------------------------------------------------- // + USDIMAGING_API virtual SdfPath Populate(UsdPrim const& prim, UsdImagingIndexProxy* index, diff --git a/pxr/usdImaging/usdImaging/rectLightAdapter.cpp b/pxr/usdImaging/usdImaging/rectLightAdapter.cpp index d291b4b1c2..3d84cabb1d 100644 --- a/pxr/usdImaging/usdImaging/rectLightAdapter.cpp +++ b/pxr/usdImaging/usdImaging/rectLightAdapter.cpp @@ -43,6 +43,22 @@ UsdImagingRectLightAdapter::~UsdImagingRectLightAdapter() { } +TfTokenVector +UsdImagingRectLightAdapter::GetImagingSubprims() +{ + return { TfToken() }; +} + +TfToken +UsdImagingRectLightAdapter::GetImagingSubprimType(TfToken const& subprim) +{ + if (subprim.IsEmpty()) { + return HdPrimTypeTokens->rectLight; + } + + return TfToken(); +} + bool UsdImagingRectLightAdapter::IsSupported(UsdImagingIndexProxy const* index) const { diff --git a/pxr/usdImaging/usdImaging/rectLightAdapter.h b/pxr/usdImaging/usdImaging/rectLightAdapter.h index df5e49a0e5..be283b28af 100644 --- a/pxr/usdImaging/usdImaging/rectLightAdapter.h +++ b/pxr/usdImaging/usdImaging/rectLightAdapter.h @@ -50,6 +50,19 @@ class UsdImagingRectLightAdapter : public UsdImagingLightAdapter { USDIMAGING_API virtual ~UsdImagingRectLightAdapter(); + + // ---------------------------------------------------------------------- // + /// \name Scene Index Support + // ---------------------------------------------------------------------- // + + USDIMAGING_API + TfTokenVector GetImagingSubprims() override; + + USDIMAGING_API + TfToken GetImagingSubprimType(TfToken const& subprim) override; + + // ---------------------------------------------------------------------- // + USDIMAGING_API virtual SdfPath Populate(UsdPrim const& prim, UsdImagingIndexProxy* index, diff --git a/pxr/usdImaging/usdImaging/sphereLightAdapter.cpp b/pxr/usdImaging/usdImaging/sphereLightAdapter.cpp index ebcde638bf..408b433685 100644 --- a/pxr/usdImaging/usdImaging/sphereLightAdapter.cpp +++ b/pxr/usdImaging/usdImaging/sphereLightAdapter.cpp @@ -42,6 +42,22 @@ UsdImagingSphereLightAdapter::~UsdImagingSphereLightAdapter() { } +TfTokenVector +UsdImagingSphereLightAdapter::GetImagingSubprims() +{ + return { TfToken() }; +} + +TfToken +UsdImagingSphereLightAdapter::GetImagingSubprimType(TfToken const& subprim) +{ + if (subprim.IsEmpty()) { + return HdPrimTypeTokens->sphereLight; + } + + return TfToken(); +} + bool UsdImagingSphereLightAdapter::IsSupported( UsdImagingIndexProxy const* index) const diff --git a/pxr/usdImaging/usdImaging/sphereLightAdapter.h b/pxr/usdImaging/usdImaging/sphereLightAdapter.h index a9a22c364d..ba568fb0ad 100644 --- a/pxr/usdImaging/usdImaging/sphereLightAdapter.h +++ b/pxr/usdImaging/usdImaging/sphereLightAdapter.h @@ -50,6 +50,20 @@ class UsdImagingSphereLightAdapter : public UsdImagingLightAdapter { USDIMAGING_API virtual ~UsdImagingSphereLightAdapter(); + + // ---------------------------------------------------------------------- // + /// \name Scene Index Support + // ---------------------------------------------------------------------- // + + USDIMAGING_API + TfTokenVector GetImagingSubprims() override; + + USDIMAGING_API + TfToken GetImagingSubprimType(TfToken const& subprim) override; + + // ---------------------------------------------------------------------- // + + USDIMAGING_API virtual SdfPath Populate(UsdPrim const& prim, UsdImagingIndexProxy* index,