Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "pxr/usd/usdLux/cylinderLight.h"
#include "pxr/usd/usdLux/nonboundableLightBase.h"
#include "pxr/usd/usdLux/sphereLight.h"
#include "pxr/usd/usdLux/meshLightAPI.h"

#include "pxr/usd/usd/schemaRegistry.h"

Expand Down Expand Up @@ -645,7 +646,8 @@ void IECoreUSD::ShaderAlgo::writeLight( const IECoreScene::ShaderNetwork *shader
pxr::TfType type = pxr::UsdSchemaRegistry::GetInstance().GetTypeFromName( pxr::TfToken( outputShader->getName() ) );
if(
!type.IsA<pxr::UsdLuxBoundableLightBase>() &&
!type.IsA<pxr::UsdLuxNonboundableLightBase>()
!type.IsA<pxr::UsdLuxNonboundableLightBase>() &&
outputShader->getName() != "MeshLight"
)
{
IECore::msg( IECore::Msg::Warning, "ShaderAlgo::writeLight", "Shader `{}` is not a valid UsdLux light type", outputShader->getName() );
Expand All @@ -655,7 +657,14 @@ void IECoreUSD::ShaderAlgo::writeLight( const IECoreScene::ShaderNetwork *shader
// Write the light itself onto the prim we've been given.

ShaderMap usdShaders;
prim.SetTypeName( pxr::TfToken( outputShader->getName() ) );
if( outputShader->getName() == "MeshLight" )
{
pxr::UsdLuxMeshLightAPI::Apply( prim );
}
else
{
prim.SetTypeName( pxr::TfToken( outputShader->getName() ) );
}
writeShaderParameterValues( outputShader, pxr::UsdShadeConnectableAPI( prim ) );
usdShaders[shaderNetwork->getOutput().shader] = pxr::UsdShadeConnectableAPI( prim );

Expand Down
150 changes: 150 additions & 0 deletions contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@

import pxr.Usd
import pxr.UsdGeom
import pxr.UsdLux

if pxr.Usd.GetVersion() < ( 0, 19, 3 ) :
pxr.Usd.Attribute.HasAuthoredValue = pxr.Usd.Attribute.HasAuthoredValueOpinion
Expand Down Expand Up @@ -3900,6 +3901,155 @@ def testWriteDomeLightFile( self ) :
self.assertEqual( light.GetTextureFileAttr().Get(), "test.exr" )
self.assertEqual( light.GetTextureFormatAttr().Get(), "latlong" )

@unittest.skipIf( pxr.Usd.GetVersion() < ( 0, 21, 11 ), "UsdLuxLightAPI not available" )
def testWriteMeshLight( self ) :

# Write to USD

fileName = os.path.join( self.temporaryDirectory(), "meshLight.usda" )
root = IECoreScene.SceneInterface.create( fileName, IECore.IndexedIO.OpenMode.Write )

lightNetwork = IECoreScene.ShaderNetwork(
shaders = {
"output" : IECoreScene.Shader( "MeshLight", "light", {} ),
},
output = "output",
)

meshLightObject = IECoreScene.MeshPrimitive.createPlane(
imath.Box2f( imath.V2f( 0, 0 ), imath.V2f( 1, 1 ) ),
imath.V2i( 16, 16 )
)

meshLight = root.createChild( "meshLight" )
meshLight.writeObject( meshLightObject, 0 )
meshLight.writeAttribute( "light", lightNetwork, 0 )

del meshLight, root

# Verify via USD API.

stage = pxr.Usd.Stage.Open( fileName )
prim = stage.GetPrimAtPath( "/meshLight" )

self.assertTrue( prim.IsValid() )
self.assertTrue( prim.IsA( pxr.UsdGeom.Mesh ) )
self.assertTrue( prim.HasAPI( pxr.UsdLux.MeshLightAPI ) )
self.assertFalse( pxr.UsdShade.MaterialBindingAPI.ComputeBoundMaterials( [ prim ] )[0][0] )

@unittest.skipIf( pxr.Usd.GetVersion() < ( 0, 21, 11 ), "UsdLuxLightAPI not available" )
def testReadMeshLight( self ) :

fileName = os.path.dirname( __file__ ) + "/data/meshLight.usda"
root = IECoreScene.SceneInterface.create( fileName, IECore.IndexedIO.OpenMode.Read )
meshLightXForm = root.child( "meshLight" )

self.assertEqual( meshLightXForm.attributeNames(), [] )
self.assertEqual( meshLightXForm.childNames(), ["meshLightMesh"] )

meshLight = meshLightXForm.child( "meshLightMesh" )

meshLightObject = meshLight.readObject( 0 )
self.assertIsInstance( meshLightObject, IECoreScene.MeshPrimitive )
self.assertTrue( meshLightObject.arePrimitiveVariablesValid() )
self.assertEqual( len( meshLightObject["P"].data ), 8 )

self.assertTrue( meshLight.hasAttribute( "light" ) )
network = meshLight.readAttribute( "light", 0 )

self.assertEqual(
network,
IECoreScene.ShaderNetwork(
shaders = {
"meshLightMesh" : IECoreScene.Shader(
"MeshLight",
"light",
{
"color" : IECore.Color3fData( imath.Color3f( 0, 1, 0 ) ),
"intensity" : IECore.FloatData( 2.0 ),
}
),
},
output = "meshLightMesh"
)
)

self.assertTrue( meshLight.hasAttribute( "surface" ) )
network = meshLight.readAttribute( "surface", 0 )

self.assertEqual(
network,
IECoreScene.ShaderNetwork(
shaders = {
"previewSurface" : IECoreScene.Shader(
"UsdPreviewSurface",
"surface",
{
"diffuseColor" : IECore.Color3fData( imath.Color3f( 0, 1, 0 ) ),
"roughness" : IECore.FloatData( 0.5 ),
}
),
},
output = ( "previewSurface", "surface" ),
)
)

self.assertIn( "__lights", root.setNames() )
self.assertEqual( root.readSet( "__lights" ), IECore.PathMatcher( [ "/meshLight/meshLightMesh" ] ) )

@unittest.skipIf( pxr.Usd.GetVersion() < ( 0, 21, 11 ), "UsdLuxLightAPI not available" )
def testRoundTripMeshLight( self ) :

# Write to USD

fileName = os.path.join( self.temporaryDirectory(), "meshLight.usda" )
root = IECoreScene.SceneInterface.create( fileName, IECore.IndexedIO.OpenMode.Write )

lightNetwork = IECoreScene.ShaderNetwork(
shaders = {
"output" : IECoreScene.Shader( "MeshLight", "light", {} ),
},
output = "output",
)
surfaceNetwork = IECoreScene.ShaderNetwork(
shaders = {
"output" : IECoreScene.Shader( "UsdPreviewSurface", "surface", {} ),
"texture" : IECoreScene.Shader( "UsdUVTexture", "surface", {} ),
},
output = "output",
connections = [ ( ( "texture", "rgb" ), ( "output", "glowColor" ) ) ],
)

meshLightObject = IECoreScene.MeshPrimitive.createPlane(
imath.Box2f( imath.V2f( 0, 0 ), imath.V2f( 1, 1 ) ),
imath.V2i( 16, 16 )
)

meshLight = root.createChild( "meshLight" )
meshLight.writeObject( meshLightObject, 0 )
meshLight.writeAttribute( "light", lightNetwork, 0 )
meshLight.writeAttribute( "surface", surfaceNetwork, 0 )

root.writeSet( "__lights", IECore.PathMatcher( [ "/meshLight" ] ) )

del meshLight, root

root = IECoreScene.SceneInterface.create( fileName, IECore.IndexedIO.OpenMode.Read )

meshLight = root.child( "meshLight" )
self.assertIn( "light", meshLight.attributeNames() )

# The Cortex shader handle is lost when converting to USD because we are only attaching
# the `MeshLightAPI` to the prim. Therefore the shader networks will not be equal, but we
# can check that the output shaders are equal.
self.assertEqual( meshLight.readAttribute( "light", 0 ).outputShader(), lightNetwork.outputShader() )

# The surface shader networks should be equivalent
self.assertEqual( meshLight.readAttribute( "surface", 0 ), surfaceNetwork )

self.assertIn( "__lights", root.setNames() )
self.assertEqual( root.readSet( "__lights" ), IECore.PathMatcher( [ "/meshLight" ] ) )

def testPointInstancerPrimvars( self ) :

# Use the USD API to author a point instancer with primvars on it.
Expand Down
35 changes: 35 additions & 0 deletions contrib/IECoreUSD/test/IECoreUSD/data/meshLight.usda
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#usda 1.0

def Xform "meshLight" (
)
{
def Material "previewMaterial"
{
token outputs:surface.connect = </meshLight/previewMaterial/previewSurface.outputs:surface>

def Shader "previewSurface"
{
uniform token info:id = "UsdPreviewSurface"
color3f inputs:diffuseColor = (0, 1, 0)
float inputs:roughness = 0.5
token outputs:surface
}
}

def Mesh "meshLightMesh" (
prepend apiSchemas = ["MeshLightAPI", "MaterialBindingAPI"]
)
{
rel material:binding = </meshLight/previewMaterial>

color3f inputs:color = (0, 1, 0)
float inputs:intensity = 2.0

# Cube
float3[] extent = [(-0.5, -0.5, -0.5), (0.5, 0.5, 0.5)]
int[] faceVertexCounts = [4, 4, 4, 4, 4, 4]
int[] faceVertexIndices = [0, 1, 3, 2, 2, 3, 5, 4, 4, 5, 7, 6, 6, 7, 1, 0, 1, 7, 5, 3, 6, 0, 2, 4]
point3f[] points = [(-0.5, -0.5, 0.5), (0.5, -0.5, 0.5), (-0.5, 0.5, 0.5), (0.5, 0.5, 0.5), (-0.5, 0.5, -0.5), (0.5, 0.5, -0.5), (-0.5, -0.5, -0.5), (0.5, -0.5, -0.5)]

}
}
Loading