diff --git a/Changes.md b/Changes.md index ee672d9983e..3d2bd789403 100644 --- a/Changes.md +++ b/Changes.md @@ -1,7 +1,10 @@ 1.4.x.x (relative to 1.4.7.0) ======= +Fixes +----- +- Cycles : Fixed rendering to the Catalogue using the batch Render node (#5905). Note that rendering a mixture of Catalogue and file outputs is still not supported, and in this case any file outputs will be ignored. 1.4.7.0 (relative to 1.4.6.0) ======= diff --git a/python/GafferCyclesTest/IECoreCyclesPreviewTest/RendererTest.py b/python/GafferCyclesTest/IECoreCyclesPreviewTest/RendererTest.py index cc882591337..c600119c924 100644 --- a/python/GafferCyclesTest/IECoreCyclesPreviewTest/RendererTest.py +++ b/python/GafferCyclesTest/IECoreCyclesPreviewTest/RendererTest.py @@ -53,10 +53,7 @@ class RendererTest( GafferTest.TestCase ) : def testObjectColor( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Interactive, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) renderer.output( "testOutput", @@ -95,7 +92,6 @@ def testObjectColor( self ) : plane.transform( imath.M44f().translate( imath.V3f( 0, 0, 1 ) ) ) renderer.render() - time.sleep( 2 ) image = IECoreImage.ImageDisplayDriver.storedImage( "testObjectColor" ) self.assertIsInstance( image, IECoreImage.ImagePrimitive ) @@ -110,10 +106,7 @@ def testObjectColor( self ) : def testQuadLightColorTexture( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Interactive, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) renderer.output( "testOutput", @@ -168,7 +161,6 @@ def testQuadLightColorTexture( self ) : light.transform( imath.M44f().rotate( imath.V3f( 0, math.pi, 0 ) ) ) renderer.render() - time.sleep( 2.0 ) # Check that we have a pure red image. @@ -185,10 +177,7 @@ def testQuadLightColorTexture( self ) : def testLightWithoutAttribute( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Batch, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) # Light destined for another renderer - we want to ignore this, and not crash. @@ -208,10 +197,7 @@ def testLightWithoutAttribute( self ) : def testBackgroundLightWithoutTexture( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Interactive, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) renderer.output( "testOutput", @@ -263,7 +249,6 @@ def testBackgroundLightWithoutTexture( self ) : light.transform( imath.M44f().rotate( imath.V3f( 0, math.pi, 0 ) ) ) renderer.render() - time.sleep( 2.0 ) # Check that we have a pure red image. @@ -279,10 +264,7 @@ def testBackgroundLightWithoutTexture( self ) : def testCrashWhenNoBackgroundLight( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Interactive, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) renderer.option( "cycles:shadingsystem", IECore.StringData( "SVM" ) ) @@ -301,14 +283,10 @@ def testCrashWhenNoBackgroundLight( self ) : # This used to crash. If it doesn't crash now, then we are happy. renderer.render() - time.sleep( 2.0 ) def testBackgroundLightBatchRender( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Batch, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) fileName = self.temporaryDirectory() / "test.exr" renderer.output( @@ -601,10 +579,7 @@ def backgroundShader( color ) : def testMultipleOutputs( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Interactive, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) renderer.output( "testOutput:beauty", @@ -727,10 +702,7 @@ def testCameraAttributeEdits( self ) : def testDisplayDriverCropWindow( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Interactive - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) renderer.camera( "testCamera", @@ -759,11 +731,6 @@ def testDisplayDriverCropWindow( self ) : renderer.option( "camera", IECore.StringData( "testCamera" ) ) renderer.render() - ## \todo We could just be running this test with a Batch mode render, - # in which case `render()` would block until the image was complete. - # But CyclesRenderer is currently hardcoded to only use IEDisplayOutputDriver - # for interactive renders. - time.sleep( 2.0 ) del renderer image = IECoreImage.ImageDisplayDriver.storedImage( "testCropWindow" ) @@ -773,10 +740,7 @@ def testDisplayDriverCropWindow( self ) : def testOutputFileCropWindow( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Batch - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) renderer.camera( "testCamera", @@ -808,10 +772,7 @@ def testOutputFileCropWindow( self ) : def testPointsWithNormals( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Interactive, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) renderer.output( "pointsWithNormals", @@ -861,7 +822,6 @@ def testPointsWithNormals( self ) : pointsObject.transform( imath.M44f().translate( imath.V3f( 0, 0, 2 ) ) ) renderer.render() - time.sleep( 2 ) del pointsObject del renderer @@ -878,10 +838,7 @@ def testPointsWithNormals( self ) : def __testMeshSmoothing( self, cube, smoothingExpected ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Interactive, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) renderer.output( "meshSmoothing", @@ -903,7 +860,6 @@ def __testMeshSmoothing( self, cube, smoothingExpected ) : cubeObject.transform( imath.M44f().translate( imath.V3f( 0, 0, 2 ) ).rotate( imath.V3f( 0, math.pi / 4.0, 0 ) ) ) renderer.render() - time.sleep( 2 ) del cubeObject del renderer @@ -958,10 +914,7 @@ def testVertexMeshNormals( self ) : def testUnsupportedPrimitiveVariables( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Batch, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) attributes = renderer.attributes( IECore.CompoundObject() ) primitive = IECoreScene.PointsPrimitive( IECore.V3fVectorData( [ imath.V3f( 0 ) ] ) ) @@ -992,10 +945,7 @@ def __testPrimitiveVariableInterpolation( self, primitive, primitiveVariable, ex attributeName = primitiveVariable if attributeName is None else attributeName - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Batch, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) # Frame the primitive so it fills the entire image. @@ -1457,10 +1407,7 @@ def testMeshUVs( self ) : def testShaderSubstitutions( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Batch, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) fileName = self.temporaryDirectory() / "test.exr" renderer.output( @@ -1537,10 +1484,7 @@ def __colorAtUV( self, image, uv, channelName = "" ) : def __testCustomAttributeType( self, primitive, prefix, customAttribute, outputPlug, data, expectedResult, maxDifference = 0.0 ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Batch, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) # Frame the primitive so it fills the entire image. @@ -1623,10 +1567,7 @@ def testCustomAttributes( self ) : def testCustomAttributePrecedence( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Interactive, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) renderer.output( "testOutput", @@ -1665,7 +1606,6 @@ def testCustomAttributePrecedence( self ) : plane.transform( imath.M44f().translate( imath.V3f( 0, 0, 1 ) ) ) renderer.render() - time.sleep( 2 ) image = IECoreImage.ImageDisplayDriver.storedImage( "testCustomAttributePrecedence" ) self.assertIsInstance( image, IECoreImage.ImagePrimitive ) @@ -1718,10 +1658,7 @@ def testMissingCyclesShader( self ) : def testMissingShaderParameter( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Batch, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) with IECore.CapturingMessageHandler() as mh : dodgyNetwork = IECoreScene.ShaderNetwork( @@ -1742,10 +1679,7 @@ def testMissingShaderParameter( self ) : def testOSLComponentConnections( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Interactive, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) renderer.output( "testOutput", @@ -1784,7 +1718,6 @@ def testOSLComponentConnections( self ) : plane.transform( imath.M44f().translate( imath.V3f( 0, 0, 1 ) ) ) renderer.render() - time.sleep( 2 ) image = IECoreImage.ImageDisplayDriver.storedImage( "testOSLComponentConnections" ) self.assertIsInstance( image, IECoreImage.ImagePrimitive ) @@ -1794,10 +1727,7 @@ def testOSLComponentConnections( self ) : def testSurfaceAttributeWithGenericShaderType( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Interactive, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) renderer.output( "testOutput", @@ -1834,7 +1764,6 @@ def testSurfaceAttributeWithGenericShaderType( self ) : plane.transform( imath.M44f().translate( imath.V3f( 0, 0, 1 ) ) ) renderer.render() - time.sleep( 2 ) image = IECoreImage.ImageDisplayDriver.storedImage( "testSurfaceAttributeWithGenericShaderType" ) self.assertIsInstance( image, IECoreImage.ImagePrimitive ) @@ -1859,10 +1788,7 @@ def __valueAtUV( self, image, uv, channelName ) : def testCustomAOV( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Interactive, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) # Custom AOVs are currently not supported in OSL mode. # See https://developer.blender.org/T73266 for further updates @@ -1934,7 +1860,6 @@ def testCustomAOV( self ) : plane.transform( imath.M44f().translate( imath.V3f( 0, 0, 1 ) ) ) renderer.render() - time.sleep( 2 ) image = IECoreImage.ImageDisplayDriver.storedImage( "testCustomValueAOV" ) self.assertIsInstance( image, IECoreImage.ImagePrimitive ) @@ -1956,10 +1881,7 @@ def testCustomAOV( self ) : def __testShaderResults( self, shader, expectedResults, maxDifference = 0.0 ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Batch, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) # Frame so our plane fills the entire image. @@ -2119,10 +2041,7 @@ def testColorArrayParameters( self ) : def testInvalidShaderParameterValues( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Batch, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) for name, value in { "sheen_weight" : IECore.StringData( "iShouldBeAFloat" ), @@ -2156,10 +2075,7 @@ def testInvalidShaderParameterValues( self ) : def testInvalidShaderEnumValue( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Batch, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) with IECore.CapturingMessageHandler() as mh : @@ -2184,10 +2100,7 @@ def testInvalidShaderEnumValue( self ) : def testUnsupportedShaderParameters( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Batch, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) with IECore.CapturingMessageHandler() as mh : @@ -2216,10 +2129,7 @@ def testUnsupportedShaderParameters( self ) : def testUSDLightColorTemperature( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Interactive, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) renderer.output( "testOutput", @@ -2270,7 +2180,6 @@ def testUSDLightColorTemperature( self ) : light.transform( imath.M44f().rotate( imath.V3f( 0, math.pi, 0 ) ) ) renderer.render() - time.sleep( 2.0 ) # Check that the color temperature has tinted the image red. @@ -2288,10 +2197,7 @@ def testUSDLightColorTemperature( self ) : def testOSLInSVMShadingSystem( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Interactive, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) renderer.option( "cycles:shadingsystem", IECore.StringData( "SVM" ) ) @@ -2336,7 +2242,6 @@ def testOSLInSVMShadingSystem( self ) : plane.transform( imath.M44f().translate( imath.V3f( 0, 0, 1 ) ) ) renderer.render() - time.sleep( 2 ) image = IECoreImage.ImageDisplayDriver.storedImage( "testOSLInSVMShadingSystem" ) self.assertIsInstance( image, IECoreImage.ImagePrimitive ) @@ -2352,10 +2257,7 @@ def testOSLInSVMShadingSystem( self ) : def testFilmOptions( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Interactive, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) # Get default values @@ -2393,10 +2295,7 @@ def testFilmOptions( self ) : def testIntegratorOptions( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Interactive, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) # Get default values @@ -2434,10 +2333,7 @@ def testIntegratorOptions( self ) : def testUnknownOptions( self ) : - renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( - "Cycles", - GafferScene.Private.IECoreScenePreview.Renderer.RenderType.Interactive, - ) + renderer = GafferScene.Private.IECoreScenePreview.Renderer.create( "Cycles" ) renderer.output( "testOutput", diff --git a/src/GafferCycles/IECoreCyclesPreview/IEDisplayOutputDriver.cpp b/src/GafferCycles/IECoreCyclesPreview/IEDisplayOutputDriver.cpp index 7f3acdc413f..69d129bf94d 100644 --- a/src/GafferCycles/IECoreCyclesPreview/IEDisplayOutputDriver.cpp +++ b/src/GafferCycles/IECoreCyclesPreview/IEDisplayOutputDriver.cpp @@ -48,11 +48,9 @@ IECORE_POP_DEFAULT_VISIBILITY namespace IECoreCycles { -IEDisplayOutputDriver::IEDisplayOutputDriver( const Imath::Box2i &displayWindow, const Imath::Box2i &dataWindow, IECore::ConstCompoundDataPtr parameters ) +IEDisplayOutputDriver::IEDisplayOutputDriver( const Imath::Box2i &displayWindow, const Imath::Box2i &dataWindow, const IECore::CompoundDataMap &layers ) : m_dataWindow( dataWindow ) { - const IECore::CompoundData *layersData = parameters->member( "layers", true ); - const IECore::CompoundDataMap &layers = layersData->readable(); const ccl::NodeEnum &typeEnum = *ccl::Pass::get_type_enum(); for( IECore::CompoundDataMap::const_iterator it = layers.begin(), eIt = layers.end(); it != eIt; ++it ) diff --git a/src/GafferCycles/IECoreCyclesPreview/IEDisplayOutputDriver.h b/src/GafferCycles/IECoreCyclesPreview/IEDisplayOutputDriver.h index 485d31d059e..7cc81968027 100644 --- a/src/GafferCycles/IECoreCyclesPreview/IEDisplayOutputDriver.h +++ b/src/GafferCycles/IECoreCyclesPreview/IEDisplayOutputDriver.h @@ -49,7 +49,7 @@ class IEDisplayOutputDriver : public ccl::OutputDriver { public: - IEDisplayOutputDriver( const Imath::Box2i &displayWindow, const Imath::Box2i &dataWindow, IECore::ConstCompoundDataPtr parameters ); + IEDisplayOutputDriver( const Imath::Box2i &displayWindow, const Imath::Box2i &dataWindow, const IECore::CompoundDataMap &layers ); ~IEDisplayOutputDriver() override; void write_render_tile( const Tile &tile ) override; diff --git a/src/GafferCycles/IECoreCyclesPreview/OIIOOutputDriver.cpp b/src/GafferCycles/IECoreCyclesPreview/OIIOOutputDriver.cpp index 1b0be431b10..5faf07b50a7 100644 --- a/src/GafferCycles/IECoreCyclesPreview/OIIOOutputDriver.cpp +++ b/src/GafferCycles/IECoreCyclesPreview/OIIOOutputDriver.cpp @@ -96,11 +96,9 @@ std::array g_channels = { { "R", "G", "B", "A" } }; namespace IECoreCycles { -OIIOOutputDriver::OIIOOutputDriver( const Imath::Box2i &displayWindow, const Imath::Box2i &dataWindow, IECore::ConstCompoundDataPtr parameters ) +OIIOOutputDriver::OIIOOutputDriver( const Imath::Box2i &displayWindow, const Imath::Box2i &dataWindow, const IECore::CompoundDataMap &layers ) : m_displayWindow( displayWindow ), m_dataWindow( dataWindow ) { - const IECore::CompoundData *layersData = parameters->member( "layers", true ); - const IECore::CompoundDataMap &layers = layersData->readable(); const ccl::NodeEnum &typeEnum = *ccl::Pass::get_type_enum(); std::vector channelNames; IECore::CompoundDataPtr params; diff --git a/src/GafferCycles/IECoreCyclesPreview/OIIOOutputDriver.h b/src/GafferCycles/IECoreCyclesPreview/OIIOOutputDriver.h index c29f4b0407a..60796b6e1c8 100644 --- a/src/GafferCycles/IECoreCyclesPreview/OIIOOutputDriver.h +++ b/src/GafferCycles/IECoreCyclesPreview/OIIOOutputDriver.h @@ -58,7 +58,7 @@ class OIIOOutputDriver : public ccl::OutputDriver { public: - OIIOOutputDriver( const Imath::Box2i &displayWindow, const Imath::Box2i &dataWindow, IECore::ConstCompoundDataPtr parameters ); + OIIOOutputDriver( const Imath::Box2i &displayWindow, const Imath::Box2i &dataWindow, const IECore::CompoundDataMap &layers ); ~OIIOOutputDriver() override; void write_render_tile( const Tile &tile ) override; diff --git a/src/GafferCycles/IECoreCyclesPreview/Renderer.cpp b/src/GafferCycles/IECoreCyclesPreview/Renderer.cpp index e3ac6f580af..f5bb1ec3b27 100644 --- a/src/GafferCycles/IECoreCyclesPreview/Renderer.cpp +++ b/src/GafferCycles/IECoreCyclesPreview/Renderer.cpp @@ -283,16 +283,12 @@ class CyclesOutput : public IECore::RefCounted public : CyclesOutput( const IECore::InternedString &name, const IECoreScene::Output *output ) - : m_passType( ccl::PASS_NONE ), m_denoise( false ), m_interactive( false ), m_lightgroup( false ) + : m_passType( ccl::PASS_NONE ), m_denoise( false ), m_useIEDisplay( output->getType() == "ieDisplay" ), m_lightgroup( false ) { m_parameters = output->parametersData()->copy(); CompoundDataMap &p = m_parameters->writable(); p["path"] = new StringData( output->getName() ); - p["driver"] = new StringData( output->getType() ); - - if( output->getType() == "ieDisplay" ) - m_interactive = true; m_denoise = parameter( output->parameters(), "denoise", false ); @@ -374,7 +370,7 @@ class CyclesOutput : public IECore::RefCounted ccl::PassType m_passType; std::string m_data; bool m_denoise; - bool m_interactive; + bool m_useIEDisplay; bool m_lightgroup; }; @@ -3116,10 +3112,6 @@ class CyclesRenderer final : public IECoreScenePreview::Renderer ccl::set clearPasses( m_scene->passes.begin(), m_scene->passes.end() ); m_scene->delete_nodes( clearPasses ); - CompoundDataPtr paramData = new CompoundData(); - - paramData->writable()["default"] = new StringData( "rgba" ); - ccl::CryptomatteType crypto = ccl::CRYPT_NONE; CompoundDataPtr layersData = new CompoundData(); @@ -3128,11 +3120,24 @@ class CyclesRenderer final : public IECoreScenePreview::Renderer InternedString cryptoMaterial; bool hasShadowCatcher = false; bool hasDenoise = false; + const bool useIEDisplay = std::any_of( + m_outputs.begin(), m_outputs.end(), + [] ( const auto &output ) { return output.second->m_useIEDisplay; } + ); for( auto &coutput : m_outputs ) { - if( ( m_renderType != Interactive && coutput.second->m_interactive ) || - ( m_renderType == Interactive && !coutput.second->m_interactive ) ) + if( coutput.second->m_useIEDisplay != useIEDisplay ) { + /// \todo Support a mix of IEDisplay and file outputs. To do + /// this we'd make a single `ccl::OutputDriver` subclass + /// that could cope with both types. + IECore::msg( + IECore::Msg::Warning, "CyclesRenderer", + fmt::format( + "Ignoring output \"{}\" because it is not compatible with ieDisplay-based outputs", + coutput.first.string() + ) + ); continue; } @@ -3243,9 +3248,15 @@ class CyclesRenderer final : public IECoreScenePreview::Renderer // Add lightgroups on the end for( auto &coutput : m_outputs ) { - if( ( m_renderType != Interactive && coutput.second->m_interactive ) || - ( m_renderType == Interactive && !coutput.second->m_interactive ) ) + if( coutput.second->m_useIEDisplay != useIEDisplay ) { + IECore::msg( + IECore::Msg::Warning, "CyclesRenderer", + fmt::format( + "Ignoring output \"{}\" because it is not compatible with ieDisplay-based outputs", + coutput.first.string() + ) + ); continue; } @@ -3267,8 +3278,6 @@ class CyclesRenderer final : public IECoreScenePreview::Renderer layersData->writable()[name] = layer; } - paramData->writable()["layers"] = layersData; - // When we reset the session, it cancels the internal PathTrace and // waits for it to finish. We need to do this _before_ calling // `set_output_driver()`, because otherwise the rendering threads @@ -3282,10 +3291,15 @@ class CyclesRenderer final : public IECoreScenePreview::Renderer film->set_cryptomatte_passes( crypto ); film->set_use_approximate_shadow_catcher( !hasShadowCatcher ); m_scene->integrator->set_use_denoise( hasDenoise ); - if( m_renderType == Interactive ) - m_session->set_output_driver( ccl::make_unique( displayWindow, dataWindow, paramData ) ); + + if( useIEDisplay ) + { + m_session->set_output_driver( ccl::make_unique( displayWindow, dataWindow, layersData->readable() ) ); + } else - m_session->set_output_driver( ccl::make_unique( displayWindow, dataWindow, paramData ) ); + { + m_session->set_output_driver( ccl::make_unique( displayWindow, dataWindow, layersData->readable() ) ); + } m_outputsChanged = false; }