Skip to content

Commit 18e92ee

Browse files
authored
Merge pull request #1509 from murraystevenson/renderAdaptorBackport
RB-10.5 Backport of #1507
2 parents e717efc + 6420b6f commit 18e92ee

File tree

4 files changed

+127
-3
lines changed

4 files changed

+127
-3
lines changed

Changes

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
10.5.x.x (relative to 10.5.15.4)
22
========
33

4+
Improvements
5+
------------
6+
7+
- ShaderNetworkAlgo : Added render adaptor API, allowing just-in-time modifications to
8+
ShaderNetworks during translation for rendering.
9+
410
10.5.15.4 (relative to 10.5.15.3)
511
========
612

SConstruct

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,12 @@
4141
#
4242
##########################################################################
4343

44-
import SCons
45-
import shutil
4644
import glob
4745
import sys
4846
import os
4947
import re
5048
import subprocess
5149
import platform
52-
import distutils
5350

5451
EnsureSConsVersion( 3, 0, 2 ) # Substfile is a default builder as of 3.0.2
5552
SConsignFile()

include/IECoreScene/ShaderNetworkAlgo.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,38 @@ IECORESCENE_API IECore::ConstCompoundDataPtr collapseSplineParameters( const IEC
154154
/// \deprecated: Use expandSplines on the whole network, which can handle input connections
155155
IECORESCENE_API IECore::ConstCompoundDataPtr expandSplineParameters( const IECore::ConstCompoundDataPtr& parametersData );
156156

157+
/// Render Adaptors
158+
/// ===============
159+
///
160+
/// Render adaptors are functions called to make "just in time" modifications to
161+
/// shader networks prior to rendering. They have access to a fully resolved
162+
/// attribute state, which can be used to drive the modifications. There is currently
163+
/// a single built-in adaptor, which uses `ShaderNetworkAlgo::applySubstitutions()`
164+
/// to allow strings such as texture paths to be substituted in from attributes that
165+
/// define them.
166+
///
167+
/// Adaptors are performance critical, so are deliberately not available via
168+
/// the Python API. They must be implemented in C++ only.
169+
170+
/// A function that adapts the shader network for rendering, given the full
171+
/// inherited `attributes` for an object. Must be threadsafe.
172+
using RenderAdaptorFunction = void (*)( ShaderNetwork *shaderNetwork, IECore::InternedString attributeName, const IECore::CompoundObject *attributes );
173+
/// A function that appends to `hash` to uniquely identify the work that will be
174+
/// performed by an AdaptorFunction. Particular attention must be paid to
175+
/// the performance of any such function, as it will be called frequently. If an
176+
/// adaptor will be a no-op, then nothing should be appended to the hash.
177+
/// Must be threadsafe.
178+
using RenderAdaptorHashFunction = void (*)( const ShaderNetwork *shaderNetwork, IECore::InternedString attributeName, const IECore::CompoundObject *attributes, IECore::MurmurHash &hash );
179+
180+
/// Registers an adaptor.
181+
IECORESCENE_API void registerRenderAdaptor( const std::string &name, RenderAdaptorHashFunction hashFunction, RenderAdaptorFunction adaptorFunction );
182+
/// Removes a previously registered adaptor with the specified name.
183+
IECORESCENE_API void deregisterRenderAdaptor( const std::string &name );
184+
185+
/// Hashes all the currently registered adaptors for `shaderNetwork`.
186+
IECORESCENE_API void hashRenderAdaptors( const ShaderNetwork *shaderNetwork, IECore::InternedString attributeName, const IECore::CompoundObject *attributes, IECore::MurmurHash &hash );
187+
/// Applies all the currently registered adaptors to `shaderNetwork`.
188+
IECORESCENE_API void applyRenderAdaptors( ShaderNetwork *shaderNetwork, IECore::InternedString attributeName, const IECore::CompoundObject *attributes );
157189

158190
} // namespace ShaderNetworkAlgo
159191

src/IECoreScene/ShaderNetworkAlgo.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1394,3 +1394,92 @@ IECore::ConstCompoundDataPtr ShaderNetworkAlgo::expandSplineParameters( const IE
13941394
return parametersData;
13951395
}
13961396
}
1397+
1398+
1399+
//////////////////////////////////////////////////////////////////////////
1400+
// Render Adaptors
1401+
//////////////////////////////////////////////////////////////////////////
1402+
1403+
namespace
1404+
{
1405+
1406+
struct RenderAdaptor
1407+
{
1408+
std::string name;
1409+
IECoreScene::ShaderNetworkAlgo::RenderAdaptorHashFunction hash;
1410+
IECoreScene::ShaderNetworkAlgo::RenderAdaptorFunction apply;
1411+
};
1412+
1413+
using RenderAdaptors = std::vector<RenderAdaptor>;
1414+
RenderAdaptors &renderAdaptors()
1415+
{
1416+
static RenderAdaptors g_renderAdaptors;
1417+
return g_renderAdaptors;
1418+
}
1419+
1420+
bool g_stringSubstitutionsRegistration = [] () {
1421+
1422+
IECoreScene::ShaderNetworkAlgo::registerRenderAdaptor(
1423+
"stringSubstitution",
1424+
// Hash
1425+
[] ( const IECoreScene::ShaderNetwork *shaderNetwork, InternedString attributeName, const IECore::CompoundObject *attributes, IECore::MurmurHash &hash ) {
1426+
shaderNetwork->hashSubstitutions( attributes, hash );
1427+
},
1428+
// Apply
1429+
[] ( IECoreScene::ShaderNetwork *shaderNetwork, InternedString attributeName, const IECore::CompoundObject *attributes ) {
1430+
shaderNetwork->applySubstitutions( attributes );
1431+
}
1432+
);
1433+
1434+
return true;
1435+
} ();
1436+
1437+
} // namespace
1438+
1439+
void ShaderNetworkAlgo::registerRenderAdaptor( const std::string &name, RenderAdaptorHashFunction hashFunction, RenderAdaptorFunction adaptorFunction )
1440+
{
1441+
// Replace existing adaptor if it exists.
1442+
RenderAdaptors &a = renderAdaptors();
1443+
for( auto &x : a )
1444+
{
1445+
if( x.name == name )
1446+
{
1447+
x.hash = hashFunction;
1448+
x.apply = adaptorFunction;
1449+
return;
1450+
}
1451+
}
1452+
// Otherwise add new adaptor.
1453+
a.push_back( { name, hashFunction, adaptorFunction } );
1454+
}
1455+
1456+
void ShaderNetworkAlgo::deregisterRenderAdaptor( const std::string &name )
1457+
{
1458+
RenderAdaptors &a = renderAdaptors();
1459+
a.erase(
1460+
std::remove_if(
1461+
a.begin(),
1462+
a.end(),
1463+
[&] ( const RenderAdaptor &x ) {
1464+
return x.name == name;
1465+
}
1466+
),
1467+
a.end()
1468+
);
1469+
}
1470+
1471+
void ShaderNetworkAlgo::hashRenderAdaptors( const IECoreScene::ShaderNetwork *shaderNetwork, InternedString attributeName, const IECore::CompoundObject *attributes, IECore::MurmurHash &hash )
1472+
{
1473+
for( const auto &x : renderAdaptors() )
1474+
{
1475+
x.hash( shaderNetwork, attributeName, attributes, hash );
1476+
}
1477+
}
1478+
1479+
void ShaderNetworkAlgo::applyRenderAdaptors( IECoreScene::ShaderNetwork *shaderNetwork, InternedString attributeName, const IECore::CompoundObject *attributes )
1480+
{
1481+
for( const auto &x : renderAdaptors() )
1482+
{
1483+
x.apply( shaderNetwork, attributeName, attributes );
1484+
}
1485+
}

0 commit comments

Comments
 (0)