Skip to content

Commit 8d1f4af

Browse files
Alex Fullerboberfly
authored andcommitted
IECoreScene : Spline ramp conversions for Arnold and Renderman native shaders.
1 parent 88b5af7 commit 8d1f4af

File tree

4 files changed

+218
-36
lines changed

4 files changed

+218
-36
lines changed

include/IECoreScene/ShaderNetworkAlgo.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,10 @@ IECORESCENE_API void expandSplines( ShaderNetwork *network, std::string targetPr
149149

150150

151151
/// \deprecated: Use collapseSplines on the whole network, which can handle input connections
152-
IECORESCENE_API IECore::ConstCompoundDataPtr collapseSplineParameters( const IECore::ConstCompoundDataPtr& parametersData );
152+
IECORESCENE_API IECore::ConstCompoundDataPtr collapseSplineParameters( const IECore::ConstCompoundDataPtr& parametersData, const std::string shaderType = "", const std::string shaderName = "" );
153153

154154
/// \deprecated: Use expandSplines on the whole network, which can handle input connections
155-
IECORESCENE_API IECore::ConstCompoundDataPtr expandSplineParameters( const IECore::ConstCompoundDataPtr& parametersData );
155+
IECORESCENE_API IECore::ConstCompoundDataPtr expandSplineParameters( const IECore::ConstCompoundDataPtr& parametersData, const std::string shaderType = "", const std::string shaderName = "" );
156156

157157

158158
} // namespace ShaderNetworkAlgo

src/IECoreScene/ShaderNetworkAlgo.cpp

Lines changed: 145 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -812,26 +812,37 @@ std::pair< size_t, size_t > getEndPointDuplication( const T &basis )
812812
}
813813

814814
template<typename Spline>
815-
void expandSpline( const InternedString &name, const Spline &spline, CompoundDataMap &newParameters )
815+
void expandSpline( const InternedString &name, const Spline &spline, CompoundDataMap &newParameters, const std::string shaderType = "", const std::string shaderName = "" )
816816
{
817817
const char *basis = "catmull-rom";
818+
// For Renderman see https://rmanwiki-26.pixar.com/space/REN26/19661691/PxrRamp
819+
const char *riBasis = "catmull-rom";
820+
// For Arnold see https://help.autodesk.com/view/ARNOL/ENU/?guid=arnold_user_guide_ac_texture_shaders_ac_texture_ramp_html
821+
int aiBasisIdx = 2;
822+
const bool isArnold = boost::starts_with( shaderType, "ai:" );
823+
818824
if( spline.basis == Spline::Basis::bezier() )
819825
{
820826
basis = "bezier";
821827
}
822828
else if( spline.basis == Spline::Basis::bSpline() )
823829
{
824830
basis = "bspline";
831+
riBasis = "bspline";
825832
}
826833
else if( spline.basis == Spline::Basis::linear() )
827834
{
828835
basis = "linear";
836+
riBasis = "linear";
837+
aiBasisIdx = 1;
829838
}
830839
else if( spline.basis == Spline::Basis::constant() )
831840
{
832841
// Also, "To maintain consistency", "constant splines ignore the first and the two last
833842
// data values."
834843
basis = "constant";
844+
riBasis = "constant";
845+
aiBasisIdx = 0;
835846
}
836847
auto [ duplicateStartPoints, duplicateEndPoints ] = getEndPointDuplication( spline.basis );
837848

@@ -844,7 +855,7 @@ void expandSpline( const InternedString &name, const Spline &spline, CompoundDat
844855
auto &values = valuesData->writable();
845856
values.reserve( spline.points.size() + duplicateStartPoints + duplicateEndPoints );
846857

847-
if( spline.points.size() )
858+
if( spline.points.size() && !isArnold )
848859
{
849860
for( size_t i = 0; i < duplicateStartPoints; i++ )
850861
{
@@ -857,7 +868,7 @@ void expandSpline( const InternedString &name, const Spline &spline, CompoundDat
857868
positions.push_back( it->first );
858869
values.push_back( it->second );
859870
}
860-
if( spline.points.size() )
871+
if( spline.points.size() && !isArnold )
861872
{
862873
for( size_t i = 0; i < duplicateEndPoints; i++ )
863874
{
@@ -866,16 +877,50 @@ void expandSpline( const InternedString &name, const Spline &spline, CompoundDat
866877
}
867878
}
868879

869-
newParameters[ name.string() + "Positions" ] = positionsData;
870-
newParameters[ name.string() + "Values" ] = valuesData;
871-
newParameters[ name.string() + "Basis" ] = new StringData( basis );
880+
if( isArnold && ( shaderName == "ramp_float" || shaderName == "ramp_rgb" ) )
881+
{
882+
newParameters[ "position" ] = positionsData;
883+
if constexpr ( std::is_same_v<Spline, SplinefColor3f> )
884+
{
885+
newParameters[ "color" ] = valuesData;
886+
}
887+
else
888+
{
889+
newParameters[ "value" ] = valuesData;
890+
}
891+
std::vector<int> interp;
892+
interp.resize( spline.points.size() );
893+
std::fill( interp.begin(), interp.end(), aiBasisIdx );
894+
newParameters[ "interpolation" ] = new IntVectorData( interp );
895+
}
896+
// Intentionally OR'd here as many Renderman shaders are OSL so search for the 'Pxr' prefix.
897+
else if( boost::starts_with( shaderType, "ri:" ) || ( boost::starts_with( shaderName, "Pxr" ) ) )
898+
{
899+
newParameters[ name.string() + "_Knots" ] = positionsData;
900+
if constexpr ( std::is_same_v<Spline, SplinefColor3f> )
901+
{
902+
newParameters[ name.string() + "_Colors" ] = valuesData;
903+
}
904+
else
905+
{
906+
newParameters[ name.string() + "_Floats" ] = valuesData;
907+
}
908+
newParameters[ name.string() + "_Interpolation" ] = new StringData( riBasis );
909+
}
910+
else
911+
{
912+
newParameters[ name.string() + "Positions" ] = positionsData;
913+
newParameters[ name.string() + "Values" ] = valuesData;
914+
newParameters[ name.string() + "Basis" ] = new StringData( basis );
915+
}
872916
}
873917

874918
template<typename SplineData>
875919
IECore::DataPtr loadSpline(
876920
const StringData *basisData,
877921
const IECore::TypedData< std::vector< typename SplineData::ValueType::XType > > *positionsData,
878-
const IECore::TypedData< std::vector< typename SplineData::ValueType::YType > > *valuesData
922+
const IECore::TypedData< std::vector< typename SplineData::ValueType::YType > > *valuesData,
923+
const bool unduplicatePoints = true
879924
)
880925
{
881926
typename SplineData::Ptr resultData = new SplineData();
@@ -896,15 +941,21 @@ IECore::DataPtr loadSpline(
896941
else if( basis == "linear" )
897942
{
898943
// Reverse the duplication we do when expanding splines
899-
unduplicateStartPoints = 1;
900-
unduplicateEndPoints = 1;
944+
if( unduplicatePoints )
945+
{
946+
unduplicateStartPoints = 1;
947+
unduplicateEndPoints = 1;
948+
}
901949
result.basis = SplineData::ValueType::Basis::linear();
902950
}
903951
else if( basis == "constant" )
904952
{
905953
// Reverse the duplication we do when expanding splines
906-
unduplicateStartPoints = 1;
907-
unduplicateEndPoints = 2;
954+
if( unduplicatePoints )
955+
{
956+
unduplicateStartPoints = 1;
957+
unduplicateEndPoints = 2;
958+
}
908959
result.basis = SplineData::ValueType::Basis::constant();
909960
}
910961
else
@@ -1040,7 +1091,7 @@ void ShaderNetworkAlgo::collapseSplines( ShaderNetwork *network, std::string tar
10401091
}
10411092

10421093
// For nodes which aren't spline adapters, we just need to deal with any parameters that are splines
1043-
ConstCompoundDataPtr collapsed = collapseSplineParameters( shader->parametersData() );
1094+
ConstCompoundDataPtr collapsed = collapseSplineParameters( shader->parametersData(), shader->getType(), shader->getName());
10441095
if( collapsed != shader->parametersData() )
10451096
{
10461097
// \todo - this const_cast is ugly, although safe because if the return from collapseSplineParameters
@@ -1167,13 +1218,13 @@ void ShaderNetworkAlgo::expandSplines( ShaderNetwork *network, std::string targe
11671218
{
11681219
ensureParametersCopy( origParameters, newParametersData, newParameters );
11691220
newParameters->erase( name );
1170-
expandSpline( name, colorSpline->readable(), *newParameters );
1221+
expandSpline( name, colorSpline->readable(), *newParameters, s.second->getType(), s.second->getName() );
11711222
}
11721223
else if( const SplineffData *floatSpline = runTimeCast<const SplineffData>( value.get() ) )
11731224
{
11741225
ensureParametersCopy( origParameters, newParametersData, newParameters );
11751226
newParameters->erase( name );
1176-
expandSpline( name, floatSpline->readable(), *newParameters );
1227+
expandSpline( name, floatSpline->readable(), *newParameters, s.second->getType(), s.second->getName() );
11771228
}
11781229
}
11791230

@@ -1289,27 +1340,80 @@ void ShaderNetworkAlgo::expandSplines( ShaderNetwork *network, std::string targe
12891340
}
12901341
}
12911342

1292-
IECore::ConstCompoundDataPtr ShaderNetworkAlgo::collapseSplineParameters( const IECore::ConstCompoundDataPtr &parametersData )
1343+
IECore::ConstCompoundDataPtr ShaderNetworkAlgo::collapseSplineParameters( const IECore::ConstCompoundDataPtr &parametersData, const std::string shaderType, const std::string shaderName )
12931344
{
12941345
const CompoundDataMap &parameters( parametersData->readable() );
12951346
CompoundDataPtr newParametersData;
12961347
CompoundDataMap *newParameters = nullptr;
12971348

1349+
std::string basisStr = "Basis";
1350+
std::string positionsStr = "Positions";
1351+
std::string valuesStr = "Values";
1352+
1353+
const bool isArnold = boost::starts_with( shaderType, "ai:" );
1354+
const bool isRenderman = boost::starts_with( shaderType, "ri:" ) || boost::starts_with( shaderName, "Pxr" );
1355+
const bool unduplicatePoints = !isArnold;
1356+
1357+
if( isArnold && ( shaderName == "ramp_float" || shaderName == "ramp_rgb" ) )
1358+
{
1359+
basisStr = "interpolation";
1360+
positionsStr = "position";
1361+
if( shaderName == "ramp_rgb" )
1362+
{
1363+
valuesStr = "color";
1364+
}
1365+
else
1366+
{
1367+
valuesStr = "value";
1368+
}
1369+
}
1370+
else if( isRenderman )
1371+
{
1372+
basisStr = "_Interpolation";
1373+
positionsStr = "_Knots";
1374+
valuesStr = "_Floats";
1375+
}
1376+
12981377
for( const auto &maybeBasis : parameters )
12991378
{
1300-
if( !boost::ends_with( maybeBasis.first.string(), "Basis" ) )
1379+
if( !boost::ends_with( maybeBasis.first.string(), basisStr ) )
13011380
{
13021381
continue;
13031382
}
1304-
const StringData *basis = runTimeCast<const StringData>( maybeBasis.second.get() );
1383+
StringDataPtr basisPtr;
1384+
const StringData *basis = runTimeCast<StringData>( maybeBasis.second.get() );
13051385
if( !basis )
13061386
{
1307-
continue;
1387+
const IntVectorData *intBasis = runTimeCast<const IntVectorData>( maybeBasis.second.get() );
1388+
if( !intBasis )
1389+
{
1390+
continue;
1391+
}
1392+
// Do int to string conversion here, using the first value of the interpolation array
1393+
if( intBasis->readable().front() == 0 )
1394+
{
1395+
basisPtr = new StringData( "constant" );
1396+
}
1397+
else if( intBasis->readable().front() == 1 )
1398+
{
1399+
basisPtr = new StringData( "linear" );
1400+
}
1401+
else if( intBasis->readable().front() == 3 )
1402+
{
1403+
basisPtr = new StringData( "monotonecubic" );
1404+
}
1405+
else
1406+
{
1407+
basisPtr = new StringData( "catmull-rom" );
1408+
}
1409+
}
1410+
else
1411+
{
1412+
basisPtr = basis->copy();
13081413
}
13091414

1310-
1311-
std::string prefix = maybeBasis.first.string().substr( 0, maybeBasis.first.string().size() - 5 );
1312-
IECore::InternedString positionsName = prefix + "Positions";
1415+
std::string prefix = maybeBasis.first.string().substr( 0, maybeBasis.first.string().size() - basisStr.size() );
1416+
IECore::InternedString positionsName = prefix + positionsStr;
13131417
const auto positionsIter = parameters.find( positionsName );
13141418
const FloatVectorData *floatPositions = nullptr;
13151419

@@ -1323,30 +1427,41 @@ IECore::ConstCompoundDataPtr ShaderNetworkAlgo::collapseSplineParameters( const
13231427
continue;
13241428
}
13251429

1326-
IECore::InternedString valuesName = prefix + "Values";
1327-
const auto valuesIter = parameters.find( valuesName );
1430+
IECore::InternedString valuesName = prefix + valuesStr;
1431+
auto valuesIter = parameters.find( valuesName );
1432+
if( valuesIter == parameters.end() && isRenderman )
1433+
{
1434+
valuesName = prefix + "_Colors";
1435+
valuesIter = parameters.find( valuesName );
1436+
}
13281437

13291438
IECore::DataPtr foundSpline;
13301439
if( valuesIter != parameters.end() )
13311440
{
13321441
if( const FloatVectorData *floatValues = runTimeCast<const FloatVectorData>( valuesIter->second.get() ) )
13331442
{
1334-
foundSpline = loadSpline<SplineffData>( basis, floatPositions, floatValues );
1443+
foundSpline = loadSpline<SplineffData>( basisPtr.get(), floatPositions, floatValues, unduplicatePoints );
13351444
}
13361445
else if( const Color3fVectorData *color3Values = runTimeCast<const Color3fVectorData>( valuesIter->second.get() ) )
13371446
{
1338-
foundSpline = loadSpline<SplinefColor3fData>( basis, floatPositions, color3Values );
1447+
foundSpline = loadSpline<SplinefColor3fData>( basisPtr.get(), floatPositions, color3Values, unduplicatePoints );
13391448
}
13401449
else if( const Color4fVectorData *color4Values = runTimeCast<const Color4fVectorData>( valuesIter->second.get() ) )
13411450
{
1342-
foundSpline = loadSpline<SplinefColor4fData>( basis, floatPositions, color4Values );
1451+
foundSpline = loadSpline<SplinefColor4fData>( basisPtr.get(), floatPositions, color4Values, unduplicatePoints );
13431452
}
13441453
}
13451454

13461455
if( foundSpline )
13471456
{
13481457
ensureParametersCopy( parameters, newParametersData, newParameters );
1349-
(*newParameters)[prefix] = foundSpline;
1458+
// Arnold ramp_rgb/ramp_float has no prefix so ensure we have a parameter name to set
1459+
std::string newParamName( "ramp" );
1460+
if( !prefix.empty() )
1461+
{
1462+
newParamName = prefix;
1463+
}
1464+
(*newParameters)[newParamName] = foundSpline;
13501465
newParameters->erase( maybeBasis.first );
13511466
newParameters->erase( positionsName );
13521467
newParameters->erase( valuesName );
@@ -1363,7 +1478,7 @@ IECore::ConstCompoundDataPtr ShaderNetworkAlgo::collapseSplineParameters( const
13631478
}
13641479
}
13651480

1366-
IECore::ConstCompoundDataPtr ShaderNetworkAlgo::expandSplineParameters( const IECore::ConstCompoundDataPtr &parametersData )
1481+
IECore::ConstCompoundDataPtr ShaderNetworkAlgo::expandSplineParameters( const IECore::ConstCompoundDataPtr &parametersData, const std::string shaderType, const std::string shaderName )
13671482
{
13681483
const CompoundDataMap &parameters( parametersData->readable() );
13691484

@@ -1376,13 +1491,13 @@ IECore::ConstCompoundDataPtr ShaderNetworkAlgo::expandSplineParameters( const IE
13761491
{
13771492
ensureParametersCopy( parameters, newParametersData, newParameters );
13781493
newParameters->erase( i.first );
1379-
expandSpline( i.first, colorSpline->readable(), *newParameters );
1494+
expandSpline( i.first, colorSpline->readable(), *newParameters, shaderType, shaderName );
13801495
}
13811496
else if( const SplineffData *floatSpline = runTimeCast<const SplineffData>( i.second.get() ) )
13821497
{
13831498
ensureParametersCopy( parameters, newParametersData, newParameters );
13841499
newParameters->erase( i.first );
1385-
expandSpline( i.first, floatSpline->readable(), *newParameters );
1500+
expandSpline( i.first, floatSpline->readable(), *newParameters, shaderType, shaderName );
13861501
}
13871502
}
13881503

src/IECoreScene/bindings/ShaderNetworkAlgoBinding.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,14 @@ void convertOSLComponentConnectionsWrapper( ShaderNetwork *network, int oslVersi
7070
ShaderNetworkAlgo::convertOSLComponentConnections( network, oslVersion );
7171
}
7272

73-
CompoundDataPtr collapseSplineParametersWrapper( CompoundDataPtr parameters )
73+
CompoundDataPtr collapseSplineParametersWrapper( CompoundDataPtr parameters, const std::string shaderType, const std::string shaderName )
7474
{
75-
return boost::const_pointer_cast< CompoundData >( ShaderNetworkAlgo::collapseSplineParameters( parameters ) );
75+
return boost::const_pointer_cast< CompoundData >( ShaderNetworkAlgo::collapseSplineParameters( parameters, shaderType, shaderName ) );
7676
}
7777

78-
CompoundDataPtr expandSplineParametersWrapper( CompoundDataPtr parameters )
78+
CompoundDataPtr expandSplineParametersWrapper( CompoundDataPtr parameters, const std::string shaderType, const std::string shaderName )
7979
{
80-
return boost::const_pointer_cast< CompoundData >( ShaderNetworkAlgo::expandSplineParameters( parameters ) );
80+
return boost::const_pointer_cast< CompoundData >( ShaderNetworkAlgo::expandSplineParameters( parameters, shaderType, shaderName ) );
8181
}
8282

8383
std::string componentConnectionAdapterLabelWrapper()

0 commit comments

Comments
 (0)