@@ -811,26 +811,35 @@ std::pair< size_t, size_t > getEndPointDuplication( const T &basis )
811
811
}
812
812
813
813
template <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 = " " )
815
815
{
816
816
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 ;
817
821
if ( spline.basis == Spline::Basis::bezier () )
818
822
{
819
823
basis = " bezier" ;
820
824
}
821
825
else if ( spline.basis == Spline::Basis::bSpline () )
822
826
{
823
827
basis = " bspline" ;
828
+ riBasis = " bspline" ;
824
829
}
825
830
else if ( spline.basis == Spline::Basis::linear () )
826
831
{
827
832
basis = " linear" ;
833
+ riBasis = " linear" ;
834
+ aiBasisIdx = 1 ;
828
835
}
829
836
else if ( spline.basis == Spline::Basis::constant () )
830
837
{
831
838
// Also, "To maintain consistency", "constant splines ignore the first and the two last
832
839
// data values."
833
840
basis = " constant" ;
841
+ riBasis = " constant" ;
842
+ aiBasisIdx = 0 ;
834
843
}
835
844
auto [ duplicateStartPoints, duplicateEndPoints ] = getEndPointDuplication ( spline.basis );
836
845
@@ -865,9 +874,42 @@ void expandSpline( const InternedString &name, const Spline &spline, CompoundDat
865
874
}
866
875
}
867
876
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
+ }
871
913
}
872
914
873
915
template <typename SplineData>
@@ -1039,7 +1081,7 @@ void ShaderNetworkAlgo::collapseSplines( ShaderNetwork *network, std::string tar
1039
1081
}
1040
1082
1041
1083
// 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 () );
1043
1085
if ( collapsed != shader->parametersData () )
1044
1086
{
1045
1087
// \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
1166
1208
{
1167
1209
ensureParametersCopy ( origParameters, newParametersData, newParameters );
1168
1210
newParameters->erase ( name );
1169
- expandSpline ( name, colorSpline->readable (), *newParameters );
1211
+ expandSpline ( name, colorSpline->readable (), *newParameters, s. second -> getType (), s. second -> getName () );
1170
1212
}
1171
1213
else if ( const SplineffData *floatSpline = runTimeCast<const SplineffData>( value.get () ) )
1172
1214
{
1173
1215
ensureParametersCopy ( origParameters, newParametersData, newParameters );
1174
1216
newParameters->erase ( name );
1175
- expandSpline ( name, floatSpline->readable (), *newParameters );
1217
+ expandSpline ( name, floatSpline->readable (), *newParameters, s. second -> getType (), s. second -> getName () );
1176
1218
}
1177
1219
}
1178
1220
@@ -1288,27 +1330,78 @@ void ShaderNetworkAlgo::expandSplines( ShaderNetwork *network, std::string targe
1288
1330
}
1289
1331
}
1290
1332
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 )
1292
1334
{
1293
1335
const CompoundDataMap ¶meters ( parametersData->readable () );
1294
1336
CompoundDataPtr newParametersData;
1295
1337
CompoundDataMap *newParameters = nullptr ;
1296
1338
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
+
1297
1365
for ( const auto &maybeBasis : parameters )
1298
1366
{
1299
- if ( !boost::ends_with ( maybeBasis.first .string (), " Basis " ) )
1367
+ if ( !boost::ends_with ( maybeBasis.first .string (), basisStr ) )
1300
1368
{
1301
1369
continue ;
1302
1370
}
1303
- const StringData *basis = runTimeCast<const StringData>( maybeBasis.second .get () );
1371
+ StringDataPtr basisPtr;
1372
+ const StringData *basis = runTimeCast<StringData>( maybeBasis.second .get () );
1304
1373
if ( !basis )
1305
1374
{
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 ();
1307
1401
}
1308
1402
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;
1312
1405
const auto positionsIter = parameters.find ( positionsName );
1313
1406
const FloatVectorData *floatPositions = nullptr ;
1314
1407
@@ -1322,30 +1415,41 @@ IECore::ConstCompoundDataPtr ShaderNetworkAlgo::collapseSplineParameters( const
1322
1415
continue ;
1323
1416
}
1324
1417
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
+ }
1327
1425
1328
1426
IECore::DataPtr foundSpline;
1329
1427
if ( valuesIter != parameters.end () )
1330
1428
{
1331
1429
if ( const FloatVectorData *floatValues = runTimeCast<const FloatVectorData>( valuesIter->second .get () ) )
1332
1430
{
1333
- foundSpline = loadSpline<SplineffData>( basis , floatPositions, floatValues );
1431
+ foundSpline = loadSpline<SplineffData>( basisPtr. get () , floatPositions, floatValues );
1334
1432
}
1335
1433
else if ( const Color3fVectorData *color3Values = runTimeCast<const Color3fVectorData>( valuesIter->second .get () ) )
1336
1434
{
1337
- foundSpline = loadSpline<SplinefColor3fData>( basis , floatPositions, color3Values );
1435
+ foundSpline = loadSpline<SplinefColor3fData>( basisPtr. get () , floatPositions, color3Values );
1338
1436
}
1339
1437
else if ( const Color4fVectorData *color4Values = runTimeCast<const Color4fVectorData>( valuesIter->second .get () ) )
1340
1438
{
1341
- foundSpline = loadSpline<SplinefColor4fData>( basis , floatPositions, color4Values );
1439
+ foundSpline = loadSpline<SplinefColor4fData>( basisPtr. get () , floatPositions, color4Values );
1342
1440
}
1343
1441
}
1344
1442
1345
1443
if ( foundSpline )
1346
1444
{
1347
1445
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;
1349
1453
newParameters->erase ( maybeBasis.first );
1350
1454
newParameters->erase ( positionsName );
1351
1455
newParameters->erase ( valuesName );
@@ -1362,7 +1466,7 @@ IECore::ConstCompoundDataPtr ShaderNetworkAlgo::collapseSplineParameters( const
1362
1466
}
1363
1467
}
1364
1468
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 )
1366
1470
{
1367
1471
const CompoundDataMap ¶meters ( parametersData->readable () );
1368
1472
@@ -1375,13 +1479,13 @@ IECore::ConstCompoundDataPtr ShaderNetworkAlgo::expandSplineParameters( const IE
1375
1479
{
1376
1480
ensureParametersCopy ( parameters, newParametersData, newParameters );
1377
1481
newParameters->erase ( i.first );
1378
- expandSpline ( i.first , colorSpline->readable (), *newParameters );
1482
+ expandSpline ( i.first , colorSpline->readable (), *newParameters, shaderType, shaderName );
1379
1483
}
1380
1484
else if ( const SplineffData *floatSpline = runTimeCast<const SplineffData>( i.second .get () ) )
1381
1485
{
1382
1486
ensureParametersCopy ( parameters, newParametersData, newParameters );
1383
1487
newParameters->erase ( i.first );
1384
- expandSpline ( i.first , floatSpline->readable (), *newParameters );
1488
+ expandSpline ( i.first , floatSpline->readable (), *newParameters, shaderType, shaderName );
1385
1489
}
1386
1490
}
1387
1491
0 commit comments