@@ -811,26 +811,35 @@ std::pair< size_t, size_t > getEndPointDuplication( const T &basis )
811811}
812812
813813template <typename Spline>
814- void expandSpline ( const InternedString &name, const Spline &spline, CompoundDataMap &newParameters )
814+ void expandSpline ( const InternedString &name, const Spline &spline, CompoundDataMap &newParameters, const std::string shaderType = " " , const std::string shaderName = " " )
815815{
816816 const char *basis = " catmull-rom" ;
817+ // For Renderman see https://rmanwiki-26.pixar.com/space/REN26/19661691/PxrRamp
818+ const char *riBasis = " catmull-rom" ;
819+ // For Arnold see https://help.autodesk.com/view/ARNOL/ENU/?guid=arnold_user_guide_ac_texture_shaders_ac_texture_ramp_html
820+ int aiBasisIdx = 2 ;
817821 if ( spline.basis == Spline::Basis::bezier () )
818822 {
819823 basis = " bezier" ;
820824 }
821825 else if ( spline.basis == Spline::Basis::bSpline () )
822826 {
823827 basis = " bspline" ;
828+ riBasis = " bspline" ;
824829 }
825830 else if ( spline.basis == Spline::Basis::linear () )
826831 {
827832 basis = " linear" ;
833+ riBasis = " linear" ;
834+ aiBasisIdx = 1 ;
828835 }
829836 else if ( spline.basis == Spline::Basis::constant () )
830837 {
831838 // Also, "To maintain consistency", "constant splines ignore the first and the two last
832839 // data values."
833840 basis = " constant" ;
841+ riBasis = " constant" ;
842+ aiBasisIdx = 0 ;
834843 }
835844 auto [ duplicateStartPoints, duplicateEndPoints ] = getEndPointDuplication ( spline.basis );
836845
@@ -865,9 +874,42 @@ void expandSpline( const InternedString &name, const Spline &spline, CompoundDat
865874 }
866875 }
867876
868- newParameters[ name.string () + " Positions" ] = positionsData;
869- newParameters[ name.string () + " Values" ] = valuesData;
870- newParameters[ name.string () + " Basis" ] = new StringData ( basis );
877+ if ( boost::starts_with ( shaderType, " ai:" ) && ( shaderName == " ramp_float" || shaderName == " ramp_rgb" ) )
878+ {
879+ newParameters[ " position" ] = positionsData;
880+ if constexpr ( std::is_same_v<Spline, SplinefColor3f> )
881+ {
882+ newParameters[ " color" ] = valuesData;
883+ }
884+ else
885+ {
886+ newParameters[ " value" ] = valuesData;
887+ }
888+ std::vector<int > interp;
889+ interp.resize ( spline.points .size () );
890+ std::fill ( interp.begin (), interp.end (), aiBasisIdx );
891+ newParameters[ " interpolation" ] = new IntVectorData ( interp );
892+ }
893+ // Intentionally OR'd here as many Renderman shaders are OSL so search for the 'Pxr' prefix.
894+ else if ( boost::starts_with ( shaderType, " ri:" ) || ( boost::starts_with ( shaderName, " Pxr" ) ) )
895+ {
896+ newParameters[ name.string () + " _Knots" ] = positionsData;
897+ if constexpr ( std::is_same_v<Spline, SplinefColor3f> )
898+ {
899+ newParameters[ name.string () + " _Colors" ] = valuesData;
900+ }
901+ else
902+ {
903+ newParameters[ name.string () + " _Floats" ] = valuesData;
904+ }
905+ newParameters[ name.string () + " _Interpolation" ] = new StringData ( riBasis );
906+ }
907+ else
908+ {
909+ newParameters[ name.string () + " Positions" ] = positionsData;
910+ newParameters[ name.string () + " Values" ] = valuesData;
911+ newParameters[ name.string () + " Basis" ] = new StringData ( basis );
912+ }
871913}
872914
873915template <typename SplineData>
@@ -1039,7 +1081,7 @@ void ShaderNetworkAlgo::collapseSplines( ShaderNetwork *network, std::string tar
10391081 }
10401082
10411083 // For nodes which aren't spline adapters, we just need to deal with any parameters that are splines
1042- ConstCompoundDataPtr collapsed = collapseSplineParameters ( shader->parametersData () );
1084+ ConstCompoundDataPtr collapsed = collapseSplineParameters ( shader->parametersData (), shader-> getType (), shader-> getName () );
10431085 if ( collapsed != shader->parametersData () )
10441086 {
10451087 // \todo - this const_cast is ugly, although safe because if the return from collapseSplineParameters
@@ -1166,13 +1208,13 @@ void ShaderNetworkAlgo::expandSplines( ShaderNetwork *network, std::string targe
11661208 {
11671209 ensureParametersCopy ( origParameters, newParametersData, newParameters );
11681210 newParameters->erase ( name );
1169- expandSpline ( name, colorSpline->readable (), *newParameters );
1211+ expandSpline ( name, colorSpline->readable (), *newParameters, s. second -> getType (), s. second -> getName () );
11701212 }
11711213 else if ( const SplineffData *floatSpline = runTimeCast<const SplineffData>( value.get () ) )
11721214 {
11731215 ensureParametersCopy ( origParameters, newParametersData, newParameters );
11741216 newParameters->erase ( name );
1175- expandSpline ( name, floatSpline->readable (), *newParameters );
1217+ expandSpline ( name, floatSpline->readable (), *newParameters, s. second -> getType (), s. second -> getName () );
11761218 }
11771219 }
11781220
@@ -1288,27 +1330,78 @@ void ShaderNetworkAlgo::expandSplines( ShaderNetwork *network, std::string targe
12881330 }
12891331}
12901332
1291- IECore::ConstCompoundDataPtr ShaderNetworkAlgo::collapseSplineParameters ( const IECore::ConstCompoundDataPtr ¶metersData )
1333+ IECore::ConstCompoundDataPtr ShaderNetworkAlgo::collapseSplineParameters ( const IECore::ConstCompoundDataPtr ¶metersData, const std::string shaderType, const std::string shaderName )
12921334{
12931335 const CompoundDataMap ¶meters ( parametersData->readable () );
12941336 CompoundDataPtr newParametersData;
12951337 CompoundDataMap *newParameters = nullptr ;
12961338
1339+ std::string basisStr = " Basis" ;
1340+ std::string positionsStr = " Positions" ;
1341+ std::string valuesStr = " Values" ;
1342+
1343+ bool isRenderman = false ;
1344+ if ( boost::starts_with ( shaderType, " ai:" ) && ( shaderName == " ramp_float" || shaderName == " ramp_rgb" ) )
1345+ {
1346+ basisStr = " interpolation" ;
1347+ positionsStr = " position" ;
1348+ if ( shaderName == " ramp_rgb" )
1349+ {
1350+ valuesStr = " color" ;
1351+ }
1352+ else
1353+ {
1354+ valuesStr = " value" ;
1355+ }
1356+ }
1357+ else if ( boost::starts_with ( shaderType, " ri:" ) || boost::starts_with ( shaderName, " Pxr" ) )
1358+ {
1359+ basisStr = " _Interpolation" ;
1360+ positionsStr = " _Knots" ;
1361+ valuesStr = " _Floats" ;
1362+ isRenderman = true ;
1363+ }
1364+
12971365 for ( const auto &maybeBasis : parameters )
12981366 {
1299- if ( !boost::ends_with ( maybeBasis.first .string (), " Basis " ) )
1367+ if ( !boost::ends_with ( maybeBasis.first .string (), basisStr ) )
13001368 {
13011369 continue ;
13021370 }
1303- const StringData *basis = runTimeCast<const StringData>( maybeBasis.second .get () );
1371+ StringDataPtr basisPtr;
1372+ const StringData *basis = runTimeCast<StringData>( maybeBasis.second .get () );
13041373 if ( !basis )
13051374 {
1306- continue ;
1375+ const IntVectorData *intBasis = runTimeCast<const IntVectorData>( maybeBasis.second .get () );
1376+ if ( !intBasis )
1377+ {
1378+ continue ;
1379+ }
1380+ // Do int to string conversion here, using the first value of the interpolation array
1381+ if ( intBasis->readable ().front () == 0 )
1382+ {
1383+ basisPtr = new StringData ( " constant" );
1384+ }
1385+ else if ( intBasis->readable ().front () == 1 )
1386+ {
1387+ basisPtr = new StringData ( " linear" );
1388+ }
1389+ else if ( intBasis->readable ().front () == 3 )
1390+ {
1391+ basisPtr = new StringData ( " monotonecubic" );
1392+ }
1393+ else
1394+ {
1395+ basisPtr = new StringData ( " catmull-rom" );
1396+ }
1397+ }
1398+ else
1399+ {
1400+ basisPtr = basis->copy ();
13071401 }
13081402
1309-
1310- std::string prefix = maybeBasis.first .string ().substr ( 0 , maybeBasis.first .string ().size () - 5 );
1311- IECore::InternedString positionsName = prefix + " Positions" ;
1403+ std::string prefix = maybeBasis.first .string ().substr ( 0 , maybeBasis.first .string ().size () - basisStr.size () );
1404+ IECore::InternedString positionsName = prefix + positionsStr;
13121405 const auto positionsIter = parameters.find ( positionsName );
13131406 const FloatVectorData *floatPositions = nullptr ;
13141407
@@ -1322,30 +1415,41 @@ IECore::ConstCompoundDataPtr ShaderNetworkAlgo::collapseSplineParameters( const
13221415 continue ;
13231416 }
13241417
1325- IECore::InternedString valuesName = prefix + " Values" ;
1326- const auto valuesIter = parameters.find ( valuesName );
1418+ IECore::InternedString valuesName = prefix + valuesStr;
1419+ auto valuesIter = parameters.find ( valuesName );
1420+ if ( valuesIter == parameters.end () && isRenderman )
1421+ {
1422+ valuesName = prefix + " _Colors" ;
1423+ valuesIter = parameters.find ( valuesName );
1424+ }
13271425
13281426 IECore::DataPtr foundSpline;
13291427 if ( valuesIter != parameters.end () )
13301428 {
13311429 if ( const FloatVectorData *floatValues = runTimeCast<const FloatVectorData>( valuesIter->second .get () ) )
13321430 {
1333- foundSpline = loadSpline<SplineffData>( basis , floatPositions, floatValues );
1431+ foundSpline = loadSpline<SplineffData>( basisPtr. get () , floatPositions, floatValues );
13341432 }
13351433 else if ( const Color3fVectorData *color3Values = runTimeCast<const Color3fVectorData>( valuesIter->second .get () ) )
13361434 {
1337- foundSpline = loadSpline<SplinefColor3fData>( basis , floatPositions, color3Values );
1435+ foundSpline = loadSpline<SplinefColor3fData>( basisPtr. get () , floatPositions, color3Values );
13381436 }
13391437 else if ( const Color4fVectorData *color4Values = runTimeCast<const Color4fVectorData>( valuesIter->second .get () ) )
13401438 {
1341- foundSpline = loadSpline<SplinefColor4fData>( basis , floatPositions, color4Values );
1439+ foundSpline = loadSpline<SplinefColor4fData>( basisPtr. get () , floatPositions, color4Values );
13421440 }
13431441 }
13441442
13451443 if ( foundSpline )
13461444 {
13471445 ensureParametersCopy ( parameters, newParametersData, newParameters );
1348- (*newParameters)[prefix] = foundSpline;
1446+ // Arnold ramp_rgb/ramp_float has no prefix so ensure we have a parameter name to set
1447+ std::string newParamName ( " ramp" );
1448+ if ( !prefix.empty () )
1449+ {
1450+ newParamName = prefix;
1451+ }
1452+ (*newParameters)[newParamName] = foundSpline;
13491453 newParameters->erase ( maybeBasis.first );
13501454 newParameters->erase ( positionsName );
13511455 newParameters->erase ( valuesName );
@@ -1362,7 +1466,7 @@ IECore::ConstCompoundDataPtr ShaderNetworkAlgo::collapseSplineParameters( const
13621466 }
13631467}
13641468
1365- IECore::ConstCompoundDataPtr ShaderNetworkAlgo::expandSplineParameters ( const IECore::ConstCompoundDataPtr ¶metersData )
1469+ IECore::ConstCompoundDataPtr ShaderNetworkAlgo::expandSplineParameters ( const IECore::ConstCompoundDataPtr ¶metersData, const std::string shaderType, const std::string shaderName )
13661470{
13671471 const CompoundDataMap ¶meters ( parametersData->readable () );
13681472
@@ -1375,13 +1479,13 @@ IECore::ConstCompoundDataPtr ShaderNetworkAlgo::expandSplineParameters( const IE
13751479 {
13761480 ensureParametersCopy ( parameters, newParametersData, newParameters );
13771481 newParameters->erase ( i.first );
1378- expandSpline ( i.first , colorSpline->readable (), *newParameters );
1482+ expandSpline ( i.first , colorSpline->readable (), *newParameters, shaderType, shaderName );
13791483 }
13801484 else if ( const SplineffData *floatSpline = runTimeCast<const SplineffData>( i.second .get () ) )
13811485 {
13821486 ensureParametersCopy ( parameters, newParametersData, newParameters );
13831487 newParameters->erase ( i.first );
1384- expandSpline ( i.first , floatSpline->readable (), *newParameters );
1488+ expandSpline ( i.first , floatSpline->readable (), *newParameters, shaderType, shaderName );
13851489 }
13861490 }
13871491
0 commit comments