| 1077 | } // namespace |
| 1078 | |
| 1079 | void ShaderNetworkAlgo::collapseRamps( ShaderNetwork *network, std::string targetPrefix ) |
| 1080 | { |
| 1081 | std::vector< IECore::InternedString > adapters; |
| 1082 | |
| 1083 | for( auto [name, shader] : network->shaders() ) |
| 1084 | { |
| 1085 | if( !boost::starts_with( shader->getType(), targetPrefix ) ) |
| 1086 | { |
| 1087 | continue; |
| 1088 | } |
| 1089 | |
| 1090 | bool isRampAdapter = shader->getType() == g_oslShader && ( |
| 1091 | shader->getName() == g_colorToArrayAdapter || shader->getName() == g_floatToArrayAdapter |
| 1092 | ); |
| 1093 | |
| 1094 | if( isRampAdapter ) |
| 1095 | { |
| 1096 | adapters.push_back( name ); |
| 1097 | continue; |
| 1098 | } |
| 1099 | |
| 1100 | // For nodes which aren't spline adapters, we just need to deal with any parameters that can become ramps |
| 1101 | ConstCompoundDataPtr collapsed = collapseRampParametersInternal( shader->parametersData(), shader->getName() ); |
| 1102 | if( collapsed != shader->parametersData() ) |
| 1103 | { |
| 1104 | // \todo - this const_cast is ugly, although safe because if the return from collapseRampParameterInternals |
| 1105 | // doesn't match the input, it is freshly allocated. Now that collapseRampParameters is fully |
| 1106 | // deprecated, and no longer visible publicly, collapseRampParametersInternal could |
| 1107 | // just return a non-const new parameter data, or nullptr if no changes are needed. |
| 1108 | network->setShader( name, std::move( new Shader( shader->getName(), shader->getType(), const_cast< CompoundData *>( collapsed.get() ) ) ) ); |
| 1109 | } |
| 1110 | } |
| 1111 | |
| 1112 | for( InternedString &name : adapters ) |
| 1113 | { |
| 1114 | // For all adapters we create, there will be a single output, but it doesn't hurt to have the |
| 1115 | // generality of this being a loop just in case. |
| 1116 | for( auto output : network->outputConnections( name ) ) |
| 1117 | { |
| 1118 | const std::string &splineValuesName = output.destination.name.string(); |
| 1119 | if( !boost::ends_with( splineValuesName, "Values" ) ) |
| 1120 | { |
| 1121 | IECore::msg( |
| 1122 | Msg::Error, "ShaderNetworkAlgo", "Invalid spline parameter name \"" + splineValuesName + "\"" |
| 1123 | ); |
| 1124 | continue; |
| 1125 | } |
| 1126 | |
| 1127 | InternedString rampName = string_view( splineValuesName ).substr( 0, splineValuesName.size() - 6 ); |
| 1128 | |
| 1129 | const IECoreScene::Shader *targetShader = network->getShader( output.destination.shader ); |
| 1130 | if( !targetShader ) |
| 1131 | { |
| 1132 | throw IECore::Exception( |
| 1133 | "Invalid connection to shader that doesn't exist \"" + output.destination.shader.string() + "\"" |
| 1134 | ); |
| 1135 | } |
| 1136 | const IECore::CompoundDataMap &targetParameters = targetShader->parameters(); |