From 0164512455fd702126d30cf14c154d93d0b2764f Mon Sep 17 00:00:00 2001 From: John Haddon Date: Thu, 25 Apr 2024 16:58:07 +0100 Subject: [PATCH 1/3] Delight Renderer : Prefer `fmt::format()` to `boost::format()` This one snuck in despite us ridding ourselves of `boost::format()` a while back. --- src/IECoreDelight/Renderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IECoreDelight/Renderer.cpp b/src/IECoreDelight/Renderer.cpp index 0fcb6972169..e670d15fe22 100644 --- a/src/IECoreDelight/Renderer.cpp +++ b/src/IECoreDelight/Renderer.cpp @@ -1635,7 +1635,7 @@ class DelightRenderer final : public IECoreScenePreview::Renderer { if( boost::starts_with( name.string(), "dl:" ) || name.string().find( ":" ) == string::npos ) { - IECore::msg( IECore::Msg::Warning, "IECoreDelight::Renderer::command", boost::format( "Unknown command \"%s\"." ) % name.c_str() ); + IECore::msg( IECore::Msg::Warning, "IECoreDelight::Renderer::command", fmt::format( "Unknown command \"{}\".", name.c_str() ) ); } return nullptr; From c95b2f77b30e59e2dd54824e44ad6e1a8c41b11e Mon Sep 17 00:00:00 2001 From: John Haddon Date: Tue, 30 Apr 2024 11:47:35 +0100 Subject: [PATCH 2/3] Delight Renderer : Fix dangling pointers The addresses we pass into the parameter list need to be valid until the `NSIBegin()` call returns. I think it's time we started to switch over to the NSI C++ API - the C API is too error-prone. --- src/IECoreDelight/Renderer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/IECoreDelight/Renderer.cpp b/src/IECoreDelight/Renderer.cpp index 00f78eff032..7e035c6762f 100644 --- a/src/IECoreDelight/Renderer.cpp +++ b/src/IECoreDelight/Renderer.cpp @@ -1323,10 +1323,10 @@ class DelightRenderer final : public IECoreScenePreview::Renderer }; } + void *handler = reinterpret_cast( &DelightRenderer::nsiErrorHandler ); + void *data = this; if( messageHandler ) { - void *handler = reinterpret_cast( &DelightRenderer::nsiErrorHandler ); - void *data = this; params.push_back( { "errorhandler", &handler, NSITypePointer, 0, 1, 0 } ); params.push_back( { "errorhandlerdata", &data, NSITypePointer, 0, 1, 0 } ); } From cf12842d99e940c39267878ef12b5e2f5d0f9e47 Mon Sep 17 00:00:00 2001 From: John Haddon Date: Tue, 30 Apr 2024 12:00:19 +0100 Subject: [PATCH 3/3] Delight Renderer : Register cloud rendering variant In an ideal world perhaps, we'd have implemented this as an option specified by DelightOptions, but that would put us in the chicken-and-egg situation where we can't make an NSI context without the cloud option, and we can't handle the other options until we have an NSI context. Although there _are_ strategies for dealing with that (see CyclesRenderer) they're complex and it would be preferable to avoid them. So instead this is implemented by registering a second "3Delight Cloud" renderer type, with the justification being that cloud rendering is a different enough operation that it's reasonable to present it to a user this way. In practicals terms there is no difference between this and a potential option, because the renderer can be specified using the standard `render:renderer` option. --- Changes.md | 3 +++ src/IECoreDelight/Renderer.cpp | 30 +++++++++++++++++++++++++++++- startup/GafferScene/renderers.py | 1 + 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/Changes.md b/Changes.md index 4fcbbc621bc..1c94b854a92 100644 --- a/Changes.md +++ b/Changes.md @@ -1,7 +1,10 @@ 1.4.x.x (relative to 1.4.2.0) ======= +Features +-------- +- 3Delight : Added "3Delight Cloud" renderer, for rendering using the 3Delight cloud. 1.4.2.0 (relative to 1.4.1.0) ======= diff --git a/src/IECoreDelight/Renderer.cpp b/src/IECoreDelight/Renderer.cpp index 7e035c6762f..0ddbe55910b 100644 --- a/src/IECoreDelight/Renderer.cpp +++ b/src/IECoreDelight/Renderer.cpp @@ -1304,7 +1304,7 @@ class DelightRenderer final : public IECoreScenePreview::Renderer public : - DelightRenderer( RenderType renderType, const std::string &fileName, const IECore::MessageHandlerPtr &messageHandler ) + DelightRenderer( RenderType renderType, const std::string &fileName, const IECore::MessageHandlerPtr &messageHandler, bool cloud = false ) : m_renderType( renderType ), m_messageHandler( messageHandler ) { const IECore::MessageHandler::Scope s( m_messageHandler.get() ); @@ -1331,6 +1331,19 @@ class DelightRenderer final : public IECoreScenePreview::Renderer params.push_back( { "errorhandlerdata", &data, NSITypePointer, 0, 1, 0 } ); } + const int one = 1; + if( cloud ) + { + if( renderType == Renderer::RenderType::Batch ) + { + params.push_back( { "cloud", &one, NSITypeInteger, 0, 1, 0 } ); + } + else + { + IECore::msg( IECore::Msg::Level::Warning, "DelightRenderer", "Cloud rendering is only available for batch renders. Rendering locally instead." ); + } + } + m_context = NSIBegin( params.size(), params.data() ); m_instanceCache = new InstanceCache( m_context, ownership() ); m_attributesCache = new AttributesCache( m_context, ownership() ); @@ -1870,4 +1883,19 @@ const std::vector DelightRenderer::g_ieMsgLevels IECoreScenePreview::Renderer::TypeDescription DelightRenderer::g_typeDescription( "3Delight" ); +struct CloudTypeDescription +{ + CloudTypeDescription() + { + IECoreScenePreview::Renderer::registerType( + "3Delight Cloud", + [] ( IECoreScenePreview::Renderer::RenderType renderType, const std::string &fileName, const IECore::MessageHandlerPtr &messageHandler ) { + return new DelightRenderer( renderType, fileName, messageHandler, /* cloud = */ true ); + } + ); + } +}; + +CloudTypeDescription g_cloudTypeDescription; + } // namespace diff --git a/startup/GafferScene/renderers.py b/startup/GafferScene/renderers.py index fbe5f47f733..8c8260607d8 100644 --- a/startup/GafferScene/renderers.py +++ b/startup/GafferScene/renderers.py @@ -54,6 +54,7 @@ def __creator( renderType, fileName, messageHandler, renderer, module ) : ( "Cycles", "GafferCycles" ), ( "Arnold", "IECoreArnold" ), ( "3Delight", "IECoreDelight" ), + ( "3Delight Cloud", "IECoreDelight" ), ] : if renderer in GafferScene.Private.IECoreScenePreview.Renderer.types() : # Already registered