Skip to content

Commit b521b7b

Browse files
FIX : Don't throw new exceptions from ShaderNetworkAlgo
1 parent 5ec874f commit b521b7b

File tree

3 files changed

+55
-35
lines changed

3 files changed

+55
-35
lines changed

src/IECore/Ramp.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -458,19 +458,6 @@ void Ramp<X,Y>::toOSL( std::string &basis, std::vector<X> &positions, std::vecto
458458
template<typename X, typename Y>
459459
int Ramp<X,Y>::oslStartPointMultiplicity() const
460460
{
461-
if( interpolation == RampInterpolation::MonotoneCubic )
462-
{
463-
// I guess the only way to handle this properly would be to do the end point duplication
464-
// and conversion from monotone to bezier in our OSL shaders ( like the PRMan and 3delight
465-
// shader libraries do ). Except that the PRMan approach has a potentially significant
466-
// downside that if the inputs are varying, the array conversion code can't be constant
467-
// folded, and you would end up doing the array processing per-shading point. 3delight
468-
// appears to have implemented their own spline handling, which may not have this problem,
469-
// but we don't want to do this ourselves. For now, not handling inputs to monotoneCubic
470-
// ramps seems pretty reasonable.
471-
throw IECore::Exception( "Cannot connect adaptors to ramp when using monotoneCubic interpolation" );
472-
}
473-
474461
// The "multiplicity" is one greater than the number of duplicates: by default, without duplication,
475462
// every control point has a multiplicity of 1, and after 1 duplicate, there is a multiplicity of 2.
476463
return getOSLEndPointDuplication( interpolation ).first + 1;

src/IECoreScene/ShaderNetworkAlgo.cpp

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,13 +1013,23 @@ struct RampInputAdapterParameters
10131013

10141014
template< typename TypedRamp >
10151015
RampInputAdapterParameters createRampInputAdapter(
1016-
ShaderNetwork *network, const TypedData<TypedRamp> *rampData,
1016+
ShaderNetwork *network, const TypedRamp &ramp,
10171017
const IECore::CompoundDataMap &newParameters, const IECore::InternedString &rampParameterName,
10181018
const ShaderNetwork::Parameter &destination
10191019
)
10201020
{
10211021
using ValueVectorData = TypedData< std::vector< typename TypedRamp::YType > >;
10221022

1023+
if( ramp.interpolation == RampInterpolation::MonotoneCubic )
1024+
{
1025+
IECore::msg(
1026+
Msg::Error, "ShaderNetworkAlgo",
1027+
"Cannot connect adaptors to ramp when using monotoneCubic interpolation: " +
1028+
destination.shader.string() + "." + destination.name.string()
1029+
);
1030+
return { "", 0, 0, 0 };
1031+
}
1032+
10231033
IECore::InternedString splineValuesName = rampParameterName.string() + "Values";
10241034
auto findValues = newParameters.find( splineValuesName );
10251035
const ValueVectorData *splineValuesData = findValues != newParameters.end() ? runTimeCast<const ValueVectorData>( findValues->second.get() ) : nullptr;
@@ -1032,12 +1042,13 @@ RampInputAdapterParameters createRampInputAdapter(
10321042

10331043
if( splineValues.size() > maxArrayInputAdapterSize )
10341044
{
1035-
throw IECore::Exception(
1036-
"Cannot handle input to " +
1037-
destination.shader.string() + "." + destination.name.string() +
1045+
IECore::msg(
1046+
Msg::Error, "ShaderNetworkAlgo",
1047+
"Cannot handle input to " + destination.shader.string() + "." + destination.name.string() +
10381048
" : expanded spline has " + std::to_string( splineValues.size() ) +
10391049
" control points, but max input adapter size is " + std::to_string( maxArrayInputAdapterSize )
10401050
);
1051+
return { "", 0, 0, 0 };
10411052
}
10421053

10431054
// Using this adapter depends on Gaffer being available, but I guess we don't really
@@ -1060,7 +1071,7 @@ RampInputAdapterParameters createRampInputAdapter(
10601071
{ destination.shader, splineValuesName }
10611072
) );
10621073

1063-
return { adapterHandle, rampData->readable().points.size(), splineValues.size(), rampData->readable().oslStartPointMultiplicity() - 1 };
1074+
return { adapterHandle, ramp.points.size(), splineValues.size(), ramp.oslStartPointMultiplicity() - 1 };
10641075
}
10651076

10661077
} // namespace
@@ -1129,28 +1140,40 @@ void ShaderNetworkAlgo::collapseRamps( ShaderNetwork *network, std::string targe
11291140
auto targetParameterIt = targetParameters.find( rampName );
11301141
if( targetParameterIt != targetParameters.end() )
11311142
{
1132-
if( const RampffData *findRampff = runTimeCast<const RampffData>( targetParameterIt->second.get() ) )
1143+
if( const RampffData *findRampffData = runTimeCast<const RampffData>( targetParameterIt->second.get() ) )
11331144
{
1134-
targetRampKnotOffset = findRampff->readable().oslStartPointMultiplicity() - 1;
1135-
targetRampSize = findRampff->readable().points.size();
1145+
const Rampff &ramp = findRampffData->readable();
1146+
if( ramp.interpolation != RampInterpolation::MonotoneCubic )
1147+
{
1148+
targetRampKnotOffset = ramp.oslStartPointMultiplicity() - 1;
1149+
targetRampSize = ramp.points.size();
1150+
}
11361151
}
1137-
else if( const RampfColor3fData *findRampfColor3f = runTimeCast<const RampfColor3fData>( targetParameterIt->second.get() ) )
1152+
else if( const RampfColor3fData *findRampfColor3fData = runTimeCast<const RampfColor3fData>( targetParameterIt->second.get() ) )
11381153
{
1139-
targetRampKnotOffset = findRampfColor3f->readable().oslStartPointMultiplicity() - 1;
1140-
targetRampSize = findRampfColor3f->readable().points.size();
1154+
const RampfColor3f &ramp = findRampfColor3fData->readable();
1155+
if( ramp.interpolation != RampInterpolation::MonotoneCubic )
1156+
{
1157+
targetRampKnotOffset = ramp.oslStartPointMultiplicity() - 1;
1158+
targetRampSize = ramp.points.size();
1159+
}
11411160
}
1142-
else if( const RampfColor4fData *findRampfColor4f = runTimeCast<const RampfColor4fData>( targetParameterIt->second.get() ) )
1161+
else if( const RampfColor4fData *findRampfColor4fData = runTimeCast<const RampfColor4fData>( targetParameterIt->second.get() ) )
11431162
{
1144-
targetRampKnotOffset = findRampfColor4f->readable().oslStartPointMultiplicity() - 1;
1145-
targetRampSize = findRampfColor4f->readable().points.size();
1163+
const RampfColor4f &ramp = findRampfColor4fData->readable();
1164+
if( ramp.interpolation != RampInterpolation::MonotoneCubic )
1165+
{
1166+
targetRampKnotOffset = ramp.oslStartPointMultiplicity() - 1;
1167+
targetRampSize = ramp.points.size();
1168+
}
11461169
}
11471170
}
11481171

11491172
if( targetRampKnotOffset == -1 )
11501173
{
11511174
IECore::msg(
11521175
Msg::Error, "ShaderNetworkAlgo",
1153-
"Invalid connection to spline parameter that doesn't exist \"" +
1176+
"Invalid connection to spline parameter that doesn't exist or can't accept connections \"" +
11541177
output.destination.shader.string() + "." + output.destination.name.string() + "\""
11551178
);
11561179
continue;
@@ -1256,7 +1279,7 @@ void ShaderNetworkAlgo::expandRamps( ShaderNetwork *network, std::string targetP
12561279
// if we remove the connection.
12571280
const ShaderNetwork::Connection connection = *it++;
12581281

1259-
const std::string &destName = connection.destination.name.string();
1282+
const std::string destName = connection.destination.name.string();
12601283
boost::smatch rampElementMatch;
12611284
if( !boost::regex_match( destName, rampElementMatch, g_rampElementRegex) )
12621285
{
@@ -1285,19 +1308,27 @@ void ShaderNetworkAlgo::expandRamps( ShaderNetwork *network, std::string targetP
12851308
if( colorRampData )
12861309
{
12871310
adapterIter->second = createRampInputAdapter(
1288-
network, colorRampData, *newParameters, parameterName, connection.destination
1311+
network, colorRampData->readable(), *newParameters, parameterName, connection.destination
12891312
);
12901313
}
12911314
else
12921315
{
12931316
adapterIter->second = createRampInputAdapter(
1294-
network, floatRampData, *newParameters, parameterName, connection.destination
1317+
network, floatRampData->readable(), *newParameters, parameterName, connection.destination
12951318
);
12961319
}
12971320
}
12981321

1322+
network->removeConnection( connection );
1323+
12991324
const RampInputAdapterParameters &adapterParms = adapterIter->second;
13001325

1326+
if( adapterParms.adapterHandle.string().size() == 0 )
1327+
{
1328+
// Can't form new connection, createRampInputAdapter should have already printed an error
1329+
continue;
1330+
}
1331+
13011332
int elementId;
13021333
std::string_view elementIdString( stringViewFromMatch( destName, rampElementMatch, 2 ) );
13031334
try
@@ -1322,8 +1353,6 @@ void ShaderNetworkAlgo::expandRamps( ShaderNetwork *network, std::string targetP
13221353
// specify unused duplicated end points for "consistency", but for simplicity, we always connect
13231354
// the first or last control point to the duplicated end points.
13241355

1325-
network->removeConnection( connection );
1326-
13271356
int outIndexMin, outIndexMax;
13281357

13291358
if( elementId == 0 )

test/IECoreScene/ShaderNetworkAlgoTest.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ def testRampConversion( self ):
407407
IECoreScene.ShaderNetworkAlgo.collapseRamps( shaderNetworkBadRampConnection )
408408
self.assertEqual( len( mh.messages ), 1 )
409409
self.assertEqual( mh.messages[0].level, IECore.Msg.Level.Error )
410-
self.assertEqual( mh.messages[0].message, 'Invalid connection to spline parameter that doesn\'t exist "test.notARampValues"' )
410+
self.assertEqual( mh.messages[0].message, 'Invalid connection to spline parameter that doesn\'t exist or can\'t accept connections "test.notARampValues"' )
411411

412412
shaderNetworkBadRampConnection = shaderNetworkExpandedGood.copy()
413413
shaderNetworkBadRampConnection.addConnection( ( ( "adapt", "out4" ), ( "test", "testffbSplineValues" ) ) )
@@ -593,9 +593,13 @@ def testRampInputs( self ):
593593
output = "testRamps"
594594
)
595595

596-
with self.assertRaisesRegex( Exception, r".*Cannot handle input to testRamps.fC3fcatmullRom\[0\].y.b : expanded spline has 35 control points, but max input adapter size is 32.*" ):
596+
with IECore.CapturingMessageHandler() as mh :
597597
IECoreScene.ShaderNetworkAlgo.convertToOSLConventions( n, 11000 )
598598

599+
self.assertEqual( len( mh.messages ), 1 )
600+
self.assertEqual( mh.messages[0].level, IECore.Msg.Level.Error )
601+
self.assertEqual( mh.messages[0].message, "Cannot handle input to testRamps.fC3fcatmullRom[0].y.b : expanded spline has 35 control points, but max input adapter size is 32" )
602+
599603
n = IECoreScene.ShaderNetwork(
600604
shaders = {
601605
"testRamps" : IECoreScene.Shader(

0 commit comments

Comments
 (0)