Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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: 1 addition & 12 deletions source/MaterialXCore/Document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,18 +93,7 @@ class Document::Cache
ImplementationPtr impl = interface->asA<Implementation>();
if (impl)
{
// Check for implementation which specifies a nodegraph as the implementation
const string& nodeGraphString = impl->getNodeGraph();
if (!nodeGraphString.empty())
{
NodeGraphPtr nodeGraph = impl->getDocument()->getNodeGraph(nodeGraphString);
if (nodeGraph)
implementationMap[interface->getQualifiedName(nodeDefString)].push_back(nodeGraph);
}
else
{
implementationMap[interface->getQualifiedName(nodeDefString)].push_back(interface);
}
implementationMap[interface->getQualifiedName(nodeDefString)].push_back(interface);
}
}
}
Expand Down
69 changes: 42 additions & 27 deletions source/MaterialXGenOsl/LibsToOso.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,7 @@ const std::string options =
" --oslCompilerPath [FILEPATH] TODO\n"
" --oslIncludePath [DIRPATH] TODO\n"
" --libraries [STRING] TODO\n"
" --removeNdPrefix [BOOLEAN] TODO\n"
" --prefix [STRING] TODO\n"
" --osoNameStrategy [STRING] TODO - either 'implementation' or 'nodedef' (default:'implementation')\n"
" --help Display the complete list of command-line options\n";

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

// Loop over the provided arguments, and store their associated values.
for (size_t i = 0; i < tokens.size(); i++)
Expand All @@ -158,10 +156,8 @@ int main(int argc, char* const argv[])
argOslIncludePath = nextToken;
else if (token == "--libraries")
argLibraries = nextToken;
else if (token == "--removeNdPrefix")
parseToken(nextToken, "boolean", argRemoveNdPrefix);
else if (token == "--prefix")
argPrefix = nextToken;
else if (token == "--osoNameStrategy")
argOsoNameStrategy = nextToken;
else if (token == "--help")
{
std::cout << "MaterialXGenOslNetwork - LibsToOso version " << mx::getVersionString() << std::endl;
Expand All @@ -185,9 +181,24 @@ int main(int argc, char* const argv[])
i++;
}

bool osoNameStrategy_implementation = true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable name looks pretty unusual, with a mix of camel case and snake case! Is there a motivation for the unique naming convention?

Copy link
Contributor Author

@ld-kerley ld-kerley Nov 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

open to alternatives here...

I'm just remapping a string based enum from the command line args - to allow for future expansion of the public interface - to a more efficient boolean.

I thought the name helped to make it clear that which of the current list of two values we're using for the enum.

In the future if we expand the public command line arg options - then we would need to refactor this internally.

The _ character visually helps separate the variable from its corresponding enumeration value

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this variable is only referenced once in the code that follows, what would you think of replacing the single variable reference with argOsoNameStrategy == "implementation", which reads clearly on its own?

If a new variable is ultimately needed here, then I'd suggest a camel case name along the lines of osoNameStrategyIsImpl, but given the context, it seems more straightforward just to omit the variable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we would prefer to store the result - instead of doing the string comparison inside the loop - but if thats your preference I can make that change. Ultimately we just need to be able to support both modes in a forward looking way.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's completely up to you, and although this doesn't seem like a big optimization opportunity, it's fine to create the new camel-case variable if you prefer.

if (argOsoNameStrategy == "implementation")
{
// do nothing this is the default
}
else if (argOsoNameStrategy == "nodedef")
{
osoNameStrategy_implementation = false;
}
else
{
std::cerr << "Unrecognized value for --osoNameStrategy '" << argOsoNameStrategy <<
"'. Must be 'implementation' or 'nodedef'" << std::endl;
return 1;
}

// Ensure we have a valid output path.
mx::FilePath outputOsoPath(argOutputOsoPath);

if (!outputOsoPath.exists() || !outputOsoPath.isDirectory())
{
outputOsoPath.createDirectory();
Expand Down Expand Up @@ -219,21 +230,17 @@ int main(int argc, char* const argv[])

// Ensure we have a valid path to the OSL compiler.
mx::FilePath oslCompilerPath(argOslCompilerPath);

if (!oslCompilerPath.exists())
{
std::cerr << "The provided path to the OSL compiler is not valid: " << oslCompilerPath.asString() << std::endl;

return 1;
}

// Ensure we have a valid path to the OSL includes.
mx::FilePath oslIncludePath(argOslIncludePath);

if (!oslIncludePath.exists() || !oslIncludePath.isDirectory())
{
std::cerr << "The provided path to the OSL includes is not valid: " << oslIncludePath.asString() << std::endl;

return 1;
}

Expand Down Expand Up @@ -337,19 +344,6 @@ int main(int argc, char* const argv[])
// Loop over all the `NodeDef` gathered in our documents from the provided libraries.
for (mx::NodeDefPtr nodeDef : librariesDoc->getNodeDefs())
{
std::string nodeName = nodeDef->getName();

// Remove the "ND_" prefix from a valid `NodeDef` name.
if (argRemoveNdPrefix)
{
if (nodeName.size() > 3 && nodeName.substr(0, 3) == "ND_")
nodeName = nodeName.substr(3);

// Add a prefix to the shader's name, both in the filename as well as inside the shader itself.
if (!argPrefix.empty())
nodeName = argPrefix + "_" + nodeName;
}

// Determine whether or not there's a valid implementation of the current `NodeDef` for the type associated
// to our OSL shader generator, i.e. OSL, and if not, skip it.
mx::InterfaceElementPtr nodeImpl = nodeDef->getImplementation(oslShaderGen->getTarget());
Expand All @@ -363,8 +357,29 @@ int main(int argc, char* const argv[])
continue;
}

// TODO: Check for the existence/validity of the `Node`?
// intention is here is to name the new node the same as the genosl implementation name
// but replacing "_genosl" with "_genoslnetwork"
std::string nodeName;
if (osoNameStrategy_implementation)
{
// name the node the same as the implementation with _genoslnetwork added as a suffix.
// NOTE : if the implementation currently has _genosl as a suffix then we remove it.
nodeName = nodeImpl->getName();
nodeName = mx::replaceSubstrings(nodeName, {{"_genosl", ""}});
nodeName += "_genoslnetwork";
}
else
{
// name the node the same as the node definition
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor note: Ideally these new comments should start with a capital letter, mirroring the coding style elsewhere in this source file.

nodeName = nodeDef->getName();
}

mx::NodePtr node = librariesDocGraph->addNodeInstance(nodeDef, nodeName);
if (!node)
{
std::cerr << "Unable to create Node instance for NodeDef - '" << nodeDef->getName() << "'" << std::endl;
return 1;
}

std::string oslShaderName = node->getName();
oslShaderGen->getSyntax().makeValidName(oslShaderName);
Expand Down
15 changes: 15 additions & 0 deletions source/MaterialXGenShader/ShaderGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,10 +318,25 @@ ShaderNodeImplPtr ShaderGenerator::getImplementation(const NodeDef& nodedef, Gen
}
else if (implElement->isA<Implementation>())
{
ImplementationPtr implementationElement = implElement->asA<Implementation>();
if (getColorManagementSystem() && getColorManagementSystem()->hasImplementation(name))
{
impl = getColorManagementSystem()->createImplementation(name);
}
else if (implementationElement->hasNodeGraph())
{
const string& nodegraphElementName = implementationElement->getNodeGraph();
NodeGraphPtr nodegraph = implElement->getDocument()->getNodeGraph(nodegraphElementName);
if (nodegraph)
{
impl = createShaderNodeImplForNodeGraph(*nodegraph);
implElement = nodegraph;
}
else
{
return nullptr;
}
}
else
{
// Try creating a new in the factory.
Expand Down