Skip to content

Commit 4f9f159

Browse files
authored
Merge pull request #1262 from johnhaddon/usdShadePackFix
Fix round-tripping of Color4f parameters through UsdShade
2 parents e3ee519 + e40fb46 commit 4f9f159

File tree

4 files changed

+124
-15
lines changed

4 files changed

+124
-15
lines changed

contrib/IECoreUSD/src/IECoreUSD/DataAlgo.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,21 @@ struct VtValueTypeNameFromData
412412
return s.FindType( TfType::Find<typename CortexTypeTraits<Imath::Color3<T>>::USDType>(), g_color );
413413
}
414414

415+
template<typename T>
416+
SdfValueTypeName operator()( const IECore::TypedData<vector<Imath::Color4<T>>> *data ) const
417+
{
418+
using ArrayType = VtArray<typename CortexTypeTraits<Imath::Color4<T>>::USDType>;
419+
const auto &s = SdfSchema::GetInstance();
420+
return s.FindType( TfType::Find<ArrayType>(), g_color );
421+
}
422+
423+
template<typename T>
424+
SdfValueTypeName operator()( const IECore::TypedData<Imath::Color4<T>> *data ) const
425+
{
426+
const auto &s = SdfSchema::GetInstance();
427+
return s.FindType( TfType::Find<typename CortexTypeTraits<Imath::Color4<T>>::USDType>(), g_color );
428+
}
429+
415430
// Generic
416431

417432
template<typename T>

contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3047,5 +3047,64 @@ def testWriteDoubleSidedAttribute( self ) :
30473047
doubleSided
30483048
)
30493049

3050+
def testColor4fShaderParameter( self ) :
3051+
3052+
network = IECoreScene.ShaderNetwork(
3053+
shaders = {
3054+
"output" : IECoreScene.Shader(
3055+
"mySurface", "surface",
3056+
{
3057+
"color4fParameter" : imath.Color4f( 1, 2, 3, 4 ),
3058+
"color4fArrayParameter" : IECore.Color4fVectorData( [
3059+
imath.Color4f( 1, 2, 3, 4 ),
3060+
imath.Color4f( 5, 6, 7, 8 ),
3061+
] ),
3062+
}
3063+
),
3064+
},
3065+
output = "output"
3066+
)
3067+
3068+
fileName = os.path.join( self.temporaryDirectory(), "shader.usda" )
3069+
root = IECoreScene.SceneInterface.create( fileName, IECore.IndexedIO.OpenMode.Write )
3070+
child = root.createChild( "child" )
3071+
child.writeAttribute( "surface", network, 0 )
3072+
3073+
del child, root
3074+
3075+
root = IECoreScene.SceneInterface.create( fileName, IECore.IndexedIO.OpenMode.Read )
3076+
child = root.child( "child" )
3077+
self.assertEqual( child.readAttribute( "surface", 0 ), network )
3078+
3079+
def testColor4fShaderParameterComponentConnections( self ) :
3080+
3081+
network = IECoreScene.ShaderNetwork(
3082+
shaders = {
3083+
"source" : IECoreScene.Shader( "noise" ),
3084+
"output" : IECoreScene.Shader(
3085+
"color_correct",
3086+
parameters = {
3087+
"input" : imath.Color4f( 1 ),
3088+
}
3089+
),
3090+
},
3091+
connections = [
3092+
( ( "source", "r" ), ( "output", "input.g" ) ),
3093+
( ( "source", "g" ), ( "output", "input.b" ) ),
3094+
( ( "source", "b" ), ( "output", "input.r" ) ),
3095+
( ( "source", "r" ), ( "output", "input.a" ) ),
3096+
],
3097+
output = "output",
3098+
)
3099+
3100+
fileName = os.path.join( self.temporaryDirectory(), "color4fComponentConnections.usda" )
3101+
root = IECoreScene.SceneInterface.create( fileName, IECore.IndexedIO.OpenMode.Write )
3102+
object = root.createChild( "object" )
3103+
object.writeAttribute( "ai:surface", network, 0.0 )
3104+
del object, root
3105+
3106+
root = IECoreScene.SceneInterface.create( fileName, IECore.IndexedIO.OpenMode.Read )
3107+
self.assertEqual( root.child( "object" ).readAttribute( "ai:surface", 0 ), network )
3108+
30503109
if __name__ == "__main__":
30513110
unittest.main()

src/IECoreScene/ShaderNetworkAlgo.cpp

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,10 @@ const InternedString g_swizzleHandle( "swizzle" );
129129
const InternedString g_packHandle( "pack" );
130130
const InternedString g_inParameterName( "in" );
131131
const InternedString g_outParameterName( "out" );
132-
const InternedString g_packInParameterNames[3] = { "in1", "in2", "in3" };
133-
const boost::regex g_componentRegex( "^(.*)\\.([rgbxyz])$" );
134-
static const char *g_vectorComponents[3] = { "x", "y", "z" };
135-
static const char *g_colorComponents[3] = { "r", "g", "b" };
132+
const InternedString g_packInParameterNames[4] = { "in1", "in2", "in3", "in4" };
133+
const boost::regex g_componentRegex( "^(.*)\\.([rgbaxyz])$" );
134+
const char *g_vectorComponents[3] = { "x", "y", "z" };
135+
const char *g_colorComponents[4] = { "r", "g", "b", "a" };
136136

137137
ShaderNetwork::Parameter convertComponentSuffix( const ShaderNetwork::Parameter &parameter, const std::string &suffix )
138138
{
@@ -240,22 +240,26 @@ void ShaderNetworkAlgo::addComponentConnectionAdapters( ShaderNetwork *network,
240240

241241
// All components won't necessarily have connections, so get
242242
// the values to fall back on for those that don't.
243-
V3f value( 0 );
243+
Color4f value( 0 );
244244
const Data *d = shader.second->parametersData()->member<Data>( parameterName );
245245
if( const V3fData *vd = runTimeCast<const V3fData>( d ) )
246246
{
247-
value = vd->readable();
247+
value = Color4f( vd->readable()[0], vd->readable()[1], vd->readable()[2], 0.0f );
248248
}
249249
else if( const Color3fData *cd = runTimeCast<const Color3fData>( d ) )
250250
{
251-
value = cd->readable();
251+
value = Color4f( cd->readable()[0], cd->readable()[1], cd->readable()[2], 0.0f );
252+
}
253+
else if( auto c4d = runTimeCast<const Color4fData>( d ) )
254+
{
255+
value = c4d->readable();
252256
}
253257

254258
// Make shader and set fallback values
255259

256260
ShaderPtr packShader = new Shader( "MaterialX/mx_pack_color", "osl:shader" );
257261
packShader->blindData()->writable()[ componentConnectionAdapterLabel() ] = g_trueData;
258-
for( int i = 0; i < 3; ++i )
262+
for( int i = 0; i < 4; ++i )
259263
{
260264
packShader->parameters()[g_packInParameterNames[i]] = new FloatData( value[i] );
261265
}
@@ -266,12 +270,12 @@ void ShaderNetworkAlgo::addComponentConnectionAdapters( ShaderNetwork *network,
266270

267271
network->addConnection( { { packHandle, g_outParameterName }, { shader.first, parameterName } } );
268272

269-
for( int i = 0; i < 3; ++i )
273+
for( int i = 0; i < 4; ++i )
270274
{
271-
ShaderNetwork::Parameter source = network->input( { shader.first, parameterName.string() + "." + g_vectorComponents[i] } );
272-
if( !source )
275+
ShaderNetwork::Parameter source = network->input( { shader.first, parameterName.string() + "." + g_colorComponents[i] } );
276+
if( !source && i < 3 )
273277
{
274-
source = network->input( { shader.first, parameterName.string() + "." + g_colorComponents[i] } );
278+
source = network->input( { shader.first, parameterName.string() + "." + g_vectorComponents[i] } );
275279
}
276280
if( source )
277281
{
@@ -330,7 +334,7 @@ void ShaderNetworkAlgo::removeComponentConnectionAdapters( ShaderNetwork *networ
330334
{
331335
const IECore::InternedString &inputName = inputIt->destination.name;
332336
int inputIndex = -1;
333-
for( int i = 0; i < 3; i++ )
337+
for( int i = 0; i < 4; i++ )
334338
{
335339
if( inputName == g_packInParameterNames[i] )
336340
{
@@ -348,7 +352,10 @@ void ShaderNetworkAlgo::removeComponentConnectionAdapters( ShaderNetwork *networ
348352
}
349353

350354
ShaderNetwork::Parameter componentDest;
351-
if( targetShader->parametersData()->member<Color3fData>( connection.destination.name ) )
355+
if(
356+
targetShader->parametersData()->member<Color4fData>( connection.destination.name ) ||
357+
targetShader->parametersData()->member<Color3fData>( connection.destination.name )
358+
)
352359
{
353360
componentDest = { connection.destination.shader, IECore::InternedString( connection.destination.name.string() + "." + g_colorComponents[inputIndex] ) };
354361
}
@@ -360,7 +367,7 @@ void ShaderNetworkAlgo::removeComponentConnectionAdapters( ShaderNetwork *networ
360367
{
361368
throw IECore::Exception( boost::str(
362369
boost::format(
363-
"removeComponentConnectionAdapters : Unrecognized type for targe parameter \"%1%.%2%\""
370+
"removeComponentConnectionAdapters : Unrecognized type for target parameter \"%1%.%2%\""
364371
) % connection.destination.shader.string() % connection.destination.name.string()
365372
) );
366373
}

test/IECoreScene/ShaderNetworkAlgoTest.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,5 +419,33 @@ def testSplineConversion( self ):
419419

420420
self.assertEqual( parmsCollapsed, parmsExpanded )
421421

422+
def testColor4ComponentConnections( self ) :
423+
424+
original = IECoreScene.ShaderNetwork(
425+
shaders = {
426+
"source" : IECoreScene.Shader( "noise" ),
427+
"output" : IECoreScene.Shader(
428+
"color_correct",
429+
parameters = {
430+
"input" : imath.Color4f( 1 ),
431+
}
432+
),
433+
},
434+
connections = [
435+
( ( "source", "r" ), ( "output", "input.g" ) ),
436+
( ( "source", "g" ), ( "output", "input.b" ) ),
437+
( ( "source", "b" ), ( "output", "input.r" ) ),
438+
( ( "source", "r" ), ( "output", "input.a" ) ),
439+
],
440+
output = "output",
441+
)
442+
443+
converted = original.copy()
444+
IECoreScene.ShaderNetworkAlgo.addComponentConnectionAdapters( converted )
445+
446+
unconverted = converted.copy()
447+
IECoreScene.ShaderNetworkAlgo.removeComponentConnectionAdapters( unconverted )
448+
self.assertEqual( unconverted, original )
449+
422450
if __name__ == "__main__":
423451
unittest.main()

0 commit comments

Comments
 (0)