4949#include " boost/algorithm/string/replace.hpp"
5050#include " boost/pointer_cast.hpp"
5151
52+ #include < regex>
53+
5254#if PXR_VERSION < 2102
5355#define IsContainer IsNodeGraph
5456#endif
@@ -98,6 +100,25 @@ void readAdditionalLightParameters( const pxr::UsdPrim &prim, IECore::CompoundDa
98100#endif
99101}
100102
103+ const std::regex g_arrayIndexFromUSDRegex ( " :i([0-9]+)$" );
104+ const std::string g_arrayIndexFromUSDFormat ( " [$1]" );
105+ IECore::InternedString fromUSDParameterName ( const pxr::TfToken &usdName )
106+ {
107+ // USD doesn't support connections to array indices. So Arnold-USD emulates
108+ // them using its own `parameter:i<N>`syntax - see https://github.com/Autodesk/arnold-usd/pull/381.
109+ // We convert these to the regular `parameter[N]` syntax during loading.
110+ return std::regex_replace ( usdName.GetString (), g_arrayIndexFromUSDRegex, g_arrayIndexFromUSDFormat );
111+ }
112+
113+ const std::regex g_arrayIndexFromCortexRegex ( " \\ [([0-9]+)\\ ]$" );
114+ const std::string g_arrayIndexFromCortexFormat ( " :i$1" );
115+ pxr::TfToken toUSDParameterName ( IECore::InternedString cortexName )
116+ {
117+ return pxr::TfToken (
118+ std::regex_replace ( cortexName.string (), g_arrayIndexFromCortexRegex, g_arrayIndexFromCortexFormat )
119+ );
120+ }
121+
101122IECoreScene::ShaderNetwork::Parameter readShaderNetworkWalk ( const pxr::SdfPath &anchorPath, const pxr::UsdShadeOutput &output, IECoreScene::ShaderNetwork &shaderNetwork );
102123
103124IECore::InternedString readShaderNetworkWalk ( const pxr::SdfPath &anchorPath, const pxr::UsdShadeConnectableAPI &usdShader, IECoreScene::ShaderNetwork &shaderNetwork )
@@ -146,7 +167,7 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co
146167 anchorPath, usdSource.GetOutput ( usdSourceName ), shaderNetwork
147168 );
148169 connections.push_back ( {
149- sourceHandle, { handle, IECore::InternedString ( i.GetBaseName (). GetString () ) }
170+ sourceHandle, { handle, fromUSDParameterName ( i.GetBaseName () ) }
150171 } );
151172 }
152173 else
@@ -160,7 +181,7 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co
160181
161182 if ( IECore::DataPtr d = IECoreUSD::DataAlgo::fromUSD ( pxr::UsdAttribute ( valueAttribute ) ) )
162183 {
163- parameters[ i.GetBaseName (). GetString () ] = d;
184+ parameters[fromUSDParameterName ( i.GetBaseName () ) ] = d;
164185 }
165186 }
166187
@@ -244,7 +265,7 @@ pxr::UsdShadeOutput IECoreUSD::ShaderAlgo::writeShaderNetwork( const IECoreScene
244265 for ( const auto &p : expandedParameters->readable () )
245266 {
246267 pxr::UsdShadeInput input = usdShader.CreateInput (
247- pxr::TfToken ( p.first . string () ),
268+ toUSDParameterName ( p.first ),
248269 DataAlgo::valueTypeName ( p.second .get () )
249270 );
250271 input.Set ( DataAlgo::toUSD ( p.second .get () ) );
@@ -278,7 +299,7 @@ pxr::UsdShadeOutput IECoreUSD::ShaderAlgo::writeShaderNetwork( const IECoreScene
278299 pxr::UsdShadeInput dest = usdShader.GetInput ( pxr::TfToken ( c.destination .name .string () ) );
279300 if ( ! dest.GetPrim ().IsValid () )
280301 {
281- dest = usdShader.CreateInput ( pxr::TfToken ( c.destination .name . string () ), pxr::SdfValueTypeNames->Token );
302+ dest = usdShader.CreateInput ( toUSDParameterName ( c.destination .name ), pxr::SdfValueTypeNames->Token );
282303 }
283304
284305 pxr::UsdShadeShader sourceUsdShader = pxr::UsdShadeShader::Get ( shaderContainer.GetStage (), shaderContainer.GetPath ().AppendChild ( pxr::TfToken ( pxr::TfMakeValidIdentifier ( c.source .shader .string () ) ) ) );
0 commit comments