Skip to content

Commit efd5fe5

Browse files
authored
Use implementation name for OSO (#2681)
Use implementation name when creating the OSO for OSL Network generator. The OSO really is the genoslnetwork implementation - so it makes sense to use that name as the naming structure has already been validated for the genosl generator. To access the implementation we need to change the document caching strategy. We cache the implementation elements in all cases - and only indirect to a nodegraph if present during code generation. If we can measure a performance difference here, then we can add additional caching in the shader generator, but i suspect it won't be measurable under normal circumstances.
1 parent 17be476 commit efd5fe5

File tree

3 files changed

+49
-39
lines changed

3 files changed

+49
-39
lines changed

source/MaterialXCore/Document.cpp

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -93,18 +93,7 @@ class Document::Cache
9393
ImplementationPtr impl = interface->asA<Implementation>();
9494
if (impl)
9595
{
96-
// Check for implementation which specifies a nodegraph as the implementation
97-
const string& nodeGraphString = impl->getNodeGraph();
98-
if (!nodeGraphString.empty())
99-
{
100-
NodeGraphPtr nodeGraph = impl->getDocument()->getNodeGraph(nodeGraphString);
101-
if (nodeGraph)
102-
implementationMap[interface->getQualifiedName(nodeDefString)].push_back(nodeGraph);
103-
}
104-
else
105-
{
106-
implementationMap[interface->getQualifiedName(nodeDefString)].push_back(interface);
107-
}
96+
implementationMap[interface->getQualifiedName(nodeDefString)].push_back(interface);
10897
}
10998
}
11099
}

source/MaterialXGenOsl/LibsToOso.cpp

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,7 @@ const std::string options =
100100
" --oslCompilerPath [FILEPATH] TODO\n"
101101
" --oslIncludePath [DIRPATH] TODO\n"
102102
" --libraries [STRING] TODO\n"
103-
" --removeNdPrefix [BOOLEAN] TODO\n"
104-
" --prefix [STRING] TODO\n"
103+
" --osoNameStrategy [STRING] TODO - either 'implementation' or 'nodedef' (default:'implementation')\n"
105104
" --help Display the complete list of command-line options\n";
106105

107106
template <class T> void parseToken(std::string token, std::string type, T& res)
@@ -137,8 +136,7 @@ int main(int argc, char* const argv[])
137136
std::string argOslCompilerPath;
138137
std::string argOslIncludePath;
139138
std::string argLibraries;
140-
bool argRemoveNdPrefix = false;
141-
std::string argPrefix;
139+
std::string argOsoNameStrategy = "implementation";
142140

143141
// Loop over the provided arguments, and store their associated values.
144142
for (size_t i = 0; i < tokens.size(); i++)
@@ -158,10 +156,8 @@ int main(int argc, char* const argv[])
158156
argOslIncludePath = nextToken;
159157
else if (token == "--libraries")
160158
argLibraries = nextToken;
161-
else if (token == "--removeNdPrefix")
162-
parseToken(nextToken, "boolean", argRemoveNdPrefix);
163-
else if (token == "--prefix")
164-
argPrefix = nextToken;
159+
else if (token == "--osoNameStrategy")
160+
argOsoNameStrategy = nextToken;
165161
else if (token == "--help")
166162
{
167163
std::cout << "MaterialXGenOslNetwork - LibsToOso version " << mx::getVersionString() << std::endl;
@@ -185,9 +181,15 @@ int main(int argc, char* const argv[])
185181
i++;
186182
}
187183

184+
if (!(argOsoNameStrategy == "implementation" || argOsoNameStrategy == "nodedef"))
185+
{
186+
std::cerr << "Unrecognized value for --osoNameStrategy '" << argOsoNameStrategy <<
187+
"'. Must be 'implementation' or 'nodedef'" << std::endl;
188+
return 1;
189+
}
190+
188191
// Ensure we have a valid output path.
189192
mx::FilePath outputOsoPath(argOutputOsoPath);
190-
191193
if (!outputOsoPath.exists() || !outputOsoPath.isDirectory())
192194
{
193195
outputOsoPath.createDirectory();
@@ -219,21 +221,17 @@ int main(int argc, char* const argv[])
219221

220222
// Ensure we have a valid path to the OSL compiler.
221223
mx::FilePath oslCompilerPath(argOslCompilerPath);
222-
223224
if (!oslCompilerPath.exists())
224225
{
225226
std::cerr << "The provided path to the OSL compiler is not valid: " << oslCompilerPath.asString() << std::endl;
226-
227227
return 1;
228228
}
229229

230230
// Ensure we have a valid path to the OSL includes.
231231
mx::FilePath oslIncludePath(argOslIncludePath);
232-
233232
if (!oslIncludePath.exists() || !oslIncludePath.isDirectory())
234233
{
235234
std::cerr << "The provided path to the OSL includes is not valid: " << oslIncludePath.asString() << std::endl;
236-
237235
return 1;
238236
}
239237

@@ -337,19 +335,6 @@ int main(int argc, char* const argv[])
337335
// Loop over all the `NodeDef` gathered in our documents from the provided libraries.
338336
for (mx::NodeDefPtr nodeDef : librariesDoc->getNodeDefs())
339337
{
340-
std::string nodeName = nodeDef->getName();
341-
342-
// Remove the "ND_" prefix from a valid `NodeDef` name.
343-
if (argRemoveNdPrefix)
344-
{
345-
if (nodeName.size() > 3 && nodeName.substr(0, 3) == "ND_")
346-
nodeName = nodeName.substr(3);
347-
348-
// Add a prefix to the shader's name, both in the filename as well as inside the shader itself.
349-
if (!argPrefix.empty())
350-
nodeName = argPrefix + "_" + nodeName;
351-
}
352-
353338
// Determine whether or not there's a valid implementation of the current `NodeDef` for the type associated
354339
// to our OSL shader generator, i.e. OSL, and if not, skip it.
355340
mx::InterfaceElementPtr nodeImpl = nodeDef->getImplementation(oslShaderGen->getTarget());
@@ -363,8 +348,29 @@ int main(int argc, char* const argv[])
363348
continue;
364349
}
365350

366-
// TODO: Check for the existence/validity of the `Node`?
351+
// Intention is here is to name the new node the same as the genosl implementation name
352+
// but replacing "_genosl" with "_genoslnetwork"
353+
std::string nodeName;
354+
if (argOsoNameStrategy == "implementation")
355+
{
356+
// Name the node the same as the implementation with _genoslnetwork added as a suffix.
357+
// NOTE : If the implementation currently has _genosl as a suffix then we remove it.
358+
nodeName = nodeImpl->getName();
359+
nodeName = mx::replaceSubstrings(nodeName, {{"_genosl", ""}});
360+
nodeName += "_genoslnetwork";
361+
}
362+
else
363+
{
364+
// Name the node the same as the node definition
365+
nodeName = nodeDef->getName();
366+
}
367+
367368
mx::NodePtr node = librariesDocGraph->addNodeInstance(nodeDef, nodeName);
369+
if (!node)
370+
{
371+
std::cerr << "Unable to create Node instance for NodeDef - '" << nodeDef->getName() << "'" << std::endl;
372+
return 1;
373+
}
368374

369375
std::string oslShaderName = node->getName();
370376
oslShaderGen->getSyntax().makeValidName(oslShaderName);

source/MaterialXGenShader/ShaderGenerator.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,10 +318,25 @@ ShaderNodeImplPtr ShaderGenerator::getImplementation(const NodeDef& nodedef, Gen
318318
}
319319
else if (implElement->isA<Implementation>())
320320
{
321+
ImplementationPtr implementationElement = implElement->asA<Implementation>();
321322
if (getColorManagementSystem() && getColorManagementSystem()->hasImplementation(name))
322323
{
323324
impl = getColorManagementSystem()->createImplementation(name);
324325
}
326+
else if (implementationElement->hasNodeGraph())
327+
{
328+
const string& nodegraphElementName = implementationElement->getNodeGraph();
329+
NodeGraphPtr nodegraph = implElement->getDocument()->getNodeGraph(nodegraphElementName);
330+
if (nodegraph)
331+
{
332+
impl = createShaderNodeImplForNodeGraph(*nodegraph);
333+
implElement = nodegraph;
334+
}
335+
else
336+
{
337+
return nullptr;
338+
}
339+
}
325340
else
326341
{
327342
// Try creating a new in the factory.

0 commit comments

Comments
 (0)