Skip to content

Commit 0a0bbd5

Browse files
ShaderNetworkAlgo::expand/collapseSpline : Support Prman convention for shaders prefixed with "Pxr"
1 parent deebeb7 commit 0a0bbd5

File tree

2 files changed

+134
-96
lines changed

2 files changed

+134
-96
lines changed

include/IECoreScene/ShaderNetworkAlgo.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,12 @@ IECORESCENE_API void collapseSplines( ShaderNetwork *network, std::string target
148148
IECORESCENE_API void expandSplines( ShaderNetwork *network, std::string targetPrefix = "" );
149149

150150

151-
/// \deprecated: Use collapseSplines on the whole network, which can handle input connections
151+
/// \deprecated: Use collapseSplines on the whole network, which can handle input connections, and supports
152+
/// different spline conventions for different renderers shader libraries
152153
IECORESCENE_API IECore::ConstCompoundDataPtr collapseSplineParameters( const IECore::ConstCompoundDataPtr& parametersData );
153154

154-
/// \deprecated: Use expandSplines on the whole network, which can handle input connections
155+
/// \deprecated: Use expandSplines on the whole network, which can handle input connections, and supports
156+
/// different spline conventions for different renderers shader libraries
155157
IECORESCENE_API IECore::ConstCompoundDataPtr expandSplineParameters( const IECore::ConstCompoundDataPtr& parametersData );
156158

157159

src/IECoreScene/ShaderNetworkAlgo.cpp

Lines changed: 130 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -811,8 +811,34 @@ std::pair< size_t, size_t > getEndPointDuplication( const T &basis )
811811
return std::make_pair( 0, 0 );
812812
}
813813

814+
std::tuple< const std::string*, const std::string*, const std::string* >
815+
lookupSplinePlugSuffixes( const std::string &shaderType, const std::string &shaderName )
816+
{
817+
// TODO - it would make sense to check if this is an OSL shader before using the OSL shader
818+
// translation, but the shader type isn't preserved when round tripping to USD, so that doesn't seem
819+
// to work
820+
//if( shaderType == "osl:shader" && boost::starts_with( shaderName, "Pxr" ) )
821+
822+
if( boost::starts_with( shaderName, "Pxr" ) )
823+
{
824+
static const std::string positions( "_Knots" );
825+
static const std::string values( "_Colors" );
826+
static const std::string basis( "_Interpolation" );
827+
//return std::make_tuple<const std::string &, const std::string &, const std::string &>( positions, values, basis );
828+
return { &positions, &values, &basis };
829+
}
830+
else
831+
{
832+
static const std::string positions( "Positions" );
833+
static const std::string values( "Values" );
834+
static const std::string basis( "Basis" );
835+
//return std::make_tuple<const std::string &, const std::string &, const std::string &>( positions, values, basis );
836+
return { &positions, &values, &basis };
837+
}
838+
}
839+
814840
template<typename Spline>
815-
void expandSpline( const InternedString &name, const Spline &spline, CompoundDataMap &newParameters )
841+
void expandSpline( const InternedString &name, const Spline &spline, CompoundDataMap &newParameters, const std::string &shaderType, const std::string &shaderName )
816842
{
817843
const char *basis = "catmull-rom";
818844
if( spline.basis == Spline::Basis::bezier() )
@@ -866,9 +892,11 @@ void expandSpline( const InternedString &name, const Spline &spline, CompoundDat
866892
}
867893
}
868894

869-
newParameters[ name.string() + "Positions" ] = positionsData;
870-
newParameters[ name.string() + "Values" ] = valuesData;
871-
newParameters[ name.string() + "Basis" ] = new StringData( basis );
895+
auto [ positionsSuffix, valuesSuffix, basisSuffix ] = lookupSplinePlugSuffixes( shaderType, shaderName );
896+
897+
newParameters[ name.string() + *positionsSuffix ] = positionsData;
898+
newParameters[ name.string() + *valuesSuffix ] = valuesData;
899+
newParameters[ name.string() + *basisSuffix ] = new StringData( basis );
872900
}
873901

874902
template<typename SplineData>
@@ -929,6 +957,96 @@ IECore::DataPtr loadSpline(
929957
return resultData;
930958
}
931959

960+
void ensureParametersCopy(
961+
const IECore::CompoundDataMap &parameters,
962+
IECore::CompoundDataPtr &parametersDataCopy, CompoundDataMap *&parametersCopy
963+
)
964+
{
965+
if( !parametersDataCopy )
966+
{
967+
parametersDataCopy = new CompoundData();
968+
parametersCopy = &parametersDataCopy->writable();
969+
*parametersCopy = parameters;
970+
}
971+
}
972+
973+
IECore::ConstCompoundDataPtr collapseSplineParametersInternal( const IECore::ConstCompoundDataPtr &parametersData, const std::string &shaderType, const std::string &shaderName )
974+
{
975+
976+
auto [ positionsSuffix, valuesSuffix, basisSuffix ] = lookupSplinePlugSuffixes( shaderType, shaderName );
977+
978+
const CompoundDataMap &parameters( parametersData->readable() );
979+
CompoundDataPtr newParametersData;
980+
CompoundDataMap *newParameters = nullptr;
981+
982+
for( const auto &maybeBasis : parameters )
983+
{
984+
if( !boost::ends_with( maybeBasis.first.string(), *basisSuffix ) )
985+
{
986+
continue;
987+
}
988+
const StringData *basis = runTimeCast<const StringData>( maybeBasis.second.get() );
989+
if( !basis )
990+
{
991+
continue;
992+
}
993+
994+
995+
std::string prefix = maybeBasis.first.string().substr( 0, maybeBasis.first.string().size() - basisSuffix->size() );
996+
IECore::InternedString positionsName = prefix + *positionsSuffix;
997+
const auto positionsIter = parameters.find( positionsName );
998+
const FloatVectorData *floatPositions = nullptr;
999+
1000+
if( positionsIter != parameters.end() )
1001+
{
1002+
floatPositions = runTimeCast<const FloatVectorData>( positionsIter->second.get() );
1003+
}
1004+
1005+
if( !floatPositions )
1006+
{
1007+
continue;
1008+
}
1009+
1010+
IECore::InternedString valuesName = prefix + *valuesSuffix;
1011+
const auto valuesIter = parameters.find( valuesName );
1012+
1013+
IECore::DataPtr foundSpline;
1014+
if( valuesIter != parameters.end() )
1015+
{
1016+
if( const FloatVectorData *floatValues = runTimeCast<const FloatVectorData>( valuesIter->second.get() ) )
1017+
{
1018+
foundSpline = loadSpline<SplineffData>( basis, floatPositions, floatValues );
1019+
}
1020+
else if( const Color3fVectorData *color3Values = runTimeCast<const Color3fVectorData>( valuesIter->second.get() ) )
1021+
{
1022+
foundSpline = loadSpline<SplinefColor3fData>( basis, floatPositions, color3Values );
1023+
}
1024+
else if( const Color4fVectorData *color4Values = runTimeCast<const Color4fVectorData>( valuesIter->second.get() ) )
1025+
{
1026+
foundSpline = loadSpline<SplinefColor4fData>( basis, floatPositions, color4Values );
1027+
}
1028+
}
1029+
1030+
if( foundSpline )
1031+
{
1032+
ensureParametersCopy( parameters, newParametersData, newParameters );
1033+
(*newParameters)[prefix] = foundSpline;
1034+
newParameters->erase( maybeBasis.first );
1035+
newParameters->erase( positionsName );
1036+
newParameters->erase( valuesName );
1037+
}
1038+
}
1039+
1040+
if( newParametersData )
1041+
{
1042+
return newParametersData;
1043+
}
1044+
else
1045+
{
1046+
return parametersData;
1047+
}
1048+
}
1049+
9321050
const std::string g_oslShader( "osl:shader" );
9331051

9341052
const std::string g_colorToArrayAdapter( "Utility/__ColorToArray" );
@@ -1003,19 +1121,6 @@ std::pair< InternedString, int > createSplineInputAdapter(
10031121
return std::make_pair( adapterHandle, getEndPointDuplication( splineData->readable().basis ).first );
10041122
}
10051123

1006-
void ensureParametersCopy(
1007-
const IECore::CompoundDataMap &parameters,
1008-
IECore::CompoundDataPtr &parametersDataCopy, CompoundDataMap *&parametersCopy
1009-
)
1010-
{
1011-
if( !parametersDataCopy )
1012-
{
1013-
parametersDataCopy = new CompoundData();
1014-
parametersCopy = &parametersDataCopy->writable();
1015-
*parametersCopy = parameters;
1016-
}
1017-
}
1018-
10191124
} // namespace
10201125

10211126
void ShaderNetworkAlgo::collapseSplines( ShaderNetwork *network, std::string targetPrefix )
@@ -1040,12 +1145,12 @@ void ShaderNetworkAlgo::collapseSplines( ShaderNetwork *network, std::string tar
10401145
}
10411146

10421147
// For nodes which aren't spline adapters, we just need to deal with any parameters that are splines
1043-
ConstCompoundDataPtr collapsed = collapseSplineParameters( shader->parametersData() );
1148+
ConstCompoundDataPtr collapsed = collapseSplineParametersInternal( shader->parametersData(), shader->getType(), shader->getName() );
10441149
if( collapsed != shader->parametersData() )
10451150
{
1046-
// \todo - this const_cast is ugly, although safe because if the return from collapseSplineParameters
1151+
// \todo - this const_cast is ugly, although safe because if the return from collapseSplineParameterInternals
10471152
// doesn't match the input, it is freshly allocated. Once collapseSplineParameters is fully
1048-
// deprecated, and no longer visible publicly, an internal version of collapseSplineParameters could
1153+
// deprecated, and no longer visible publicly, an internal version of collapseSplineParametersInternal could
10491154
// just return a non-const new parameter data, or nullptr if no changes are needed.
10501155
network->setShader( name, std::move( new Shader( shader->getName(), shader->getType(), const_cast< CompoundData *>( collapsed.get() ) ) ) );
10511156
}
@@ -1167,13 +1272,13 @@ void ShaderNetworkAlgo::expandSplines( ShaderNetwork *network, std::string targe
11671272
{
11681273
ensureParametersCopy( origParameters, newParametersData, newParameters );
11691274
newParameters->erase( name );
1170-
expandSpline( name, colorSpline->readable(), *newParameters );
1275+
expandSpline( name, colorSpline->readable(), *newParameters, s.second->getType(), s.second->getName() );
11711276
}
11721277
else if( const SplineffData *floatSpline = runTimeCast<const SplineffData>( value.get() ) )
11731278
{
11741279
ensureParametersCopy( origParameters, newParametersData, newParameters );
11751280
newParameters->erase( name );
1176-
expandSpline( name, floatSpline->readable(), *newParameters );
1281+
expandSpline( name, floatSpline->readable(), *newParameters, s.second->getType(), s.second->getName() );
11771282
}
11781283
}
11791284

@@ -1291,76 +1396,7 @@ void ShaderNetworkAlgo::expandSplines( ShaderNetwork *network, std::string targe
12911396

12921397
IECore::ConstCompoundDataPtr ShaderNetworkAlgo::collapseSplineParameters( const IECore::ConstCompoundDataPtr &parametersData )
12931398
{
1294-
const CompoundDataMap &parameters( parametersData->readable() );
1295-
CompoundDataPtr newParametersData;
1296-
CompoundDataMap *newParameters = nullptr;
1297-
1298-
for( const auto &maybeBasis : parameters )
1299-
{
1300-
if( !boost::ends_with( maybeBasis.first.string(), "Basis" ) )
1301-
{
1302-
continue;
1303-
}
1304-
const StringData *basis = runTimeCast<const StringData>( maybeBasis.second.get() );
1305-
if( !basis )
1306-
{
1307-
continue;
1308-
}
1309-
1310-
1311-
std::string prefix = maybeBasis.first.string().substr( 0, maybeBasis.first.string().size() - 5 );
1312-
IECore::InternedString positionsName = prefix + "Positions";
1313-
const auto positionsIter = parameters.find( positionsName );
1314-
const FloatVectorData *floatPositions = nullptr;
1315-
1316-
if( positionsIter != parameters.end() )
1317-
{
1318-
floatPositions = runTimeCast<const FloatVectorData>( positionsIter->second.get() );
1319-
}
1320-
1321-
if( !floatPositions )
1322-
{
1323-
continue;
1324-
}
1325-
1326-
IECore::InternedString valuesName = prefix + "Values";
1327-
const auto valuesIter = parameters.find( valuesName );
1328-
1329-
IECore::DataPtr foundSpline;
1330-
if( valuesIter != parameters.end() )
1331-
{
1332-
if( const FloatVectorData *floatValues = runTimeCast<const FloatVectorData>( valuesIter->second.get() ) )
1333-
{
1334-
foundSpline = loadSpline<SplineffData>( basis, floatPositions, floatValues );
1335-
}
1336-
else if( const Color3fVectorData *color3Values = runTimeCast<const Color3fVectorData>( valuesIter->second.get() ) )
1337-
{
1338-
foundSpline = loadSpline<SplinefColor3fData>( basis, floatPositions, color3Values );
1339-
}
1340-
else if( const Color4fVectorData *color4Values = runTimeCast<const Color4fVectorData>( valuesIter->second.get() ) )
1341-
{
1342-
foundSpline = loadSpline<SplinefColor4fData>( basis, floatPositions, color4Values );
1343-
}
1344-
}
1345-
1346-
if( foundSpline )
1347-
{
1348-
ensureParametersCopy( parameters, newParametersData, newParameters );
1349-
(*newParameters)[prefix] = foundSpline;
1350-
newParameters->erase( maybeBasis.first );
1351-
newParameters->erase( positionsName );
1352-
newParameters->erase( valuesName );
1353-
}
1354-
}
1355-
1356-
if( newParametersData )
1357-
{
1358-
return newParametersData;
1359-
}
1360-
else
1361-
{
1362-
return parametersData;
1363-
}
1399+
return collapseSplineParametersInternal( parametersData, "", "" );
13641400
}
13651401

13661402
IECore::ConstCompoundDataPtr ShaderNetworkAlgo::expandSplineParameters( const IECore::ConstCompoundDataPtr &parametersData )
@@ -1376,13 +1412,13 @@ IECore::ConstCompoundDataPtr ShaderNetworkAlgo::expandSplineParameters( const IE
13761412
{
13771413
ensureParametersCopy( parameters, newParametersData, newParameters );
13781414
newParameters->erase( i.first );
1379-
expandSpline( i.first, colorSpline->readable(), *newParameters );
1415+
expandSpline( i.first, colorSpline->readable(), *newParameters, "", "" );
13801416
}
13811417
else if( const SplineffData *floatSpline = runTimeCast<const SplineffData>( i.second.get() ) )
13821418
{
13831419
ensureParametersCopy( parameters, newParametersData, newParameters );
13841420
newParameters->erase( i.first );
1385-
expandSpline( i.first, floatSpline->readable(), *newParameters );
1421+
expandSpline( i.first, floatSpline->readable(), *newParameters, "", "" );
13861422
}
13871423
}
13881424

0 commit comments

Comments
 (0)