Skip to content

Commit

Permalink
Merge pull request #58 from Esri/arnold-material-deduplication
Browse files Browse the repository at this point in the history
Arnold Material Creation Improvements
  • Loading branch information
mistafunk authored Jan 10, 2020
2 parents bea4cb3 + 64e74fe commit efac535
Show file tree
Hide file tree
Showing 13 changed files with 341 additions and 201 deletions.
2 changes: 2 additions & 0 deletions src/serlio/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ add_library(${SERLIO_TARGET} SHARED
prtModifier/polyModifier/polyModifierNode.cpp
prtMaterial/ArnoldMaterialNode.cpp
prtMaterial/MaterialInfo.cpp
prtMaterial/MaterialUtils.cpp
prtMaterial/PRTMaterialNode.cpp
util/Utilities.cpp
util/ResolveMapCache.cpp
Expand All @@ -41,6 +42,7 @@ if(CMAKE_GENERATOR MATCHES "Visual Studio.+")
prtModifier/polyModifier/polyModifierNode.h
prtMaterial/ArnoldMaterialNode.h
prtMaterial/MaterialInfo.h
prtMaterial/MaterialUtils.h
prtMaterial/PRTMaterialNode.h
util/Utilities.h
util/ResolveMapCache.h
Expand Down
235 changes: 93 additions & 142 deletions src/serlio/prtMaterial/ArnoldMaterialNode.cpp

Large diffs are not rendered by default.

9 changes: 4 additions & 5 deletions src/serlio/prtMaterial/ArnoldMaterialNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,12 @@ class ArnoldMaterialNode : public MPxNode {
}

private:
void buildMaterialShaderScript(MELScriptBuilder& sb, const MaterialInfo& matInfo, const std::wstring& shaderName,
const std::wstring& shadingGroupName, const std::wstring& meshName,
const int faceStart, const int faceEnd);
void appendToMaterialScriptBuilder(MELScriptBuilder& sb, const MaterialInfo& matInfo,
const std::wstring& shaderBaseName, const std::wstring& shadingEngineName) const;

void setUvTransformAttrs(MELScriptBuilder& sb, const std::wstring& uvSet, const MaterialTrafo& trafo);
void setUvTransformAttrs(MELScriptBuilder& sb, const std::wstring& uvSet, const MaterialTrafo& trafo) const;

std::wstring createMapShader(MELScriptBuilder& sb, const std::string& mapFile, const MaterialTrafo& mapTrafo,
const std::wstring& shaderName, const std::wstring& uvSet, const bool raw,
const bool alpha);
const bool alpha) const;
};
68 changes: 68 additions & 0 deletions src/serlio/prtMaterial/MaterialInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,71 @@ bool MaterialInfo::equals(const MaterialInfo& o) const {
specularmapTrafo == o.specularmapTrafo;
// clang-format on
}

bool MaterialInfo::operator<(const MaterialInfo& rhs) const {
// clang-format off
{ int c = bumpMap.compare(rhs.bumpMap); if (c != 0) return (c < 0); }
{ int c = colormap.compare(rhs.colormap); if (c != 0) return (c < 0); }
{ int c = dirtmap.compare(rhs.dirtmap); if (c != 0) return (c < 0); }
{ int c = emissiveMap.compare(rhs.emissiveMap); if (c != 0) return (c < 0); }
{ int c = metallicMap.compare(rhs.metallicMap); if (c != 0) return (c < 0); }
{ int c = normalMap.compare(rhs.normalMap); if (c != 0) return (c < 0); }
{ int c = occlusionMap.compare(rhs.occlusionMap); if (c != 0) return (c < 0); }
{ int c = opacityMap.compare(rhs.opacityMap); if (c != 0) return (c < 0); }
{ int c = roughnessMap.compare(rhs.roughnessMap); if (c != 0) return (c < 0); }
{ int c = specularMap.compare(rhs.specularMap); if (c != 0) return (c < 0); }

if (opacity > rhs.opacity) return false;
if (opacity < rhs.opacity) return true;

if (metallic > rhs.metallic) return false;
if (metallic < rhs.metallic) return true;

if (roughness > rhs.roughness) return false;
if (roughness < rhs.roughness) return true;

if (ambientColor > rhs.ambientColor) return false;
if (ambientColor < rhs.ambientColor) return true;

if (diffuseColor > rhs.diffuseColor) return false;
if (diffuseColor < rhs.diffuseColor) return true;

if (emissiveColor > rhs.emissiveColor) return false;
if (emissiveColor < rhs.emissiveColor) return true;

if (specularColor > rhs.specularColor) return false;
if (specularColor < rhs.specularColor) return true;

if (specularmapTrafo > rhs.specularmapTrafo) return false;
if (specularmapTrafo < rhs.specularmapTrafo) return true;

if (bumpmapTrafo > rhs.bumpmapTrafo) return false;
if (bumpmapTrafo < rhs.bumpmapTrafo) return true;

if (dirtmapTrafo > rhs.dirtmapTrafo) return false;
if (dirtmapTrafo < rhs.dirtmapTrafo) return true;

if (emissivemapTrafo > rhs.emissivemapTrafo) return false;
if (emissivemapTrafo < rhs.emissivemapTrafo) return true;

if (metallicmapTrafo > rhs.metallicmapTrafo) return false;
if (metallicmapTrafo < rhs.metallicmapTrafo) return true;

if (normalmapTrafo > rhs.normalmapTrafo) return false;
if (normalmapTrafo < rhs.normalmapTrafo) return true;

if (occlusionmapTrafo > rhs.occlusionmapTrafo) return false;
if (occlusionmapTrafo < rhs.occlusionmapTrafo) return true;

if (opacitymapTrafo > rhs.opacitymapTrafo) return false;
if (opacitymapTrafo < rhs.opacitymapTrafo) return true;

if (roughnessmapTrafo > rhs.roughnessmapTrafo) return false;
if (roughnessmapTrafo < rhs.roughnessmapTrafo) return true;

if (specularmapTrafo > rhs.specularmapTrafo) return false;
if (specularmapTrafo < rhs.specularmapTrafo) return true;
// clang-format on

return false; // equality
}
2 changes: 2 additions & 0 deletions src/serlio/prtMaterial/MaterialInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ class MaterialInfo {

bool equals(const MaterialInfo& o) const;

bool operator<(const MaterialInfo& rhs) const;

private:
static std::string getTexture(adsk::Data::Handle& sHandle, const std::string& texName);
static double getDouble(adsk::Data::Handle& sHandle, const std::string& name);
Expand Down
117 changes: 117 additions & 0 deletions src/serlio/prtMaterial/MaterialUtils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#include "prtMaterial/MaterialUtils.h"

#include "util/MArrayWrapper.h"
#include "util/MItDependencyNodesWrapper.h"
#include "util/MayaUtilities.h"

#include "maya/MItDependencyNodes.h"
#include "maya/MPlugArray.h"
#include "maya/adskDataAssociations.h"
#include "maya/adskDataStream.h"

namespace {

MObject findNamedObject(const std::wstring& name, MFn::Type fnType) {
MStatus status;
MItDependencyNodes nodeIt(fnType, &status);
MCHECK(status);

for (const auto& nodeObj : MItDependencyNodesWrapper(nodeIt)) {
MFnDependencyNode node(nodeObj);
if (std::wcscmp(node.name().asWChar(), name.c_str()) == 0)
return nodeObj;
}

return MObject::kNullObj;
}

} // namespace

namespace MaterialUtils {

MStatus getMeshName(MString& meshName, const MPlug& plug) {
MStatus status;
bool searchEnded = false;

for (MPlug curPlug = plug; !searchEnded;) {
searchEnded = true;
MPlugArray connectedPlugs;
curPlug.connectedTo(connectedPlugs, false, true, &status);
MCHECK(status);
if (!connectedPlugs.length()) {
return MStatus::kFailure;
}
for (const auto& connectedPlug : mu::makeMArrayConstWrapper(connectedPlugs)) {
MFnDependencyNode connectedDepNode(connectedPlug.node(), &status);
MCHECK(status);
MObject connectedDepNodeObj = connectedDepNode.object(&status);
MCHECK(status);
if (connectedDepNodeObj.hasFn(MFn::kMesh)) {
meshName = connectedDepNode.name(&status);
MCHECK(status);
break;
}
if (connectedDepNodeObj.hasFn(MFn::kGroupParts)) {
curPlug = connectedDepNode.findPlug("outputGeometry", true, &status);
MCHECK(status);
searchEnded = false;
break;
}
}
}

return MStatus::kSuccess;
}

MaterialCache getMaterialsByStructure(const adsk::Data::Structure& materialStructure) {
MaterialCache existingMaterialInfos;

MStatus status;
MItDependencyNodes shaderIt(MFn::kShadingEngine, &status);
MCHECK(status);
for (const auto& nodeObj : MItDependencyNodesWrapper(shaderIt)) {
MFnDependencyNode node(nodeObj);

const adsk::Data::Associations* materialMetadata = node.metadata(&status);
MCHECK(status);

if (materialMetadata == nullptr)
continue;

adsk::Data::Associations materialAssociations(materialMetadata);
adsk::Data::Channel* matChannel = materialAssociations.findChannel(gPRTMatChannel);

if (matChannel == nullptr)
continue;

adsk::Data::Stream* matStream = matChannel->findDataStream(gPRTMatStream);
if ((matStream == nullptr) || (matStream->elementCount() != 1))
continue;

const adsk::Data::Handle matSHandle = matStream->element(0);
if (!matSHandle.usesStructure(materialStructure))
continue;

existingMaterialInfos.emplace(matSHandle, node.name().asWChar());
}

return existingMaterialInfos;
}

void assignMaterialMetadata(const adsk::Data::Structure& materialStructure, const adsk::Data::Handle& streamHandle,
const std::wstring& shadingEngineName) {
MObject shadingEngineObj = findNamedObject(shadingEngineName, MFn::kShadingEngine);
MFnDependencyNode shadingEngine(shadingEngineObj);

adsk::Data::Associations newMetadata;
adsk::Data::Channel newChannel = newMetadata.channel(gPRTMatChannel);
adsk::Data::Stream newStream(materialStructure, gPRTMatStream);
newChannel.setDataStream(newStream);
newMetadata.setChannel(newChannel);
adsk::Data::Handle handle(streamHandle);
handle.makeUnique();
newStream.setElement(0, handle);
shadingEngine.setMetadata(newMetadata);
}

} // namespace MaterialUtils
21 changes: 21 additions & 0 deletions src/serlio/prtMaterial/MaterialUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#include "prtMaterial/MaterialInfo.h"

#include "maya/MPlug.h"
#include "maya/MStatus.h"
#include "maya/MString.h"

#include <map>

namespace MaterialUtils {

MStatus getMeshName(MString& meshName, const MPlug& plug);

using MaterialCache = std::map<MaterialInfo, std::wstring>;
MaterialCache getMaterialsByStructure(const adsk::Data::Structure& materialStructure);

void assignMaterialMetadata(const adsk::Data::Structure& materialStructure, const adsk::Data::Handle& streamHandle,
const std::wstring& shadingEngineName);

} // namespace MaterialUtils
47 changes: 6 additions & 41 deletions src/serlio/prtMaterial/PRTMaterialNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,16 @@
#include "prtMaterial/PRTMaterialNode.h"

#include "prtMaterial/MaterialInfo.h"
#include "prtMaterial/MaterialUtils.h"

#include "prtModifier/PRTModifierAction.h"

#include "util/MArrayWrapper.h"
#include "util/MItDependencyNodesWrapper.h"
#include "util/MayaUtilities.h"
#include "util/Utilities.h"

#include "PRTContext.h"
#include "serlioPlugin.h"

#include "prt/StringUtils.h"

#include "maya/MFnMesh.h"
#include "maya/MFnTypedAttribute.h"
#include "maya/MGlobal.h"
Expand All @@ -40,11 +38,8 @@
#include "maya/adskDataAssociations.h"
#include "maya/adskDataStream.h"

#include <algorithm>
#include <array>
#include <cstdio>
#include <set>
#include <sstream>

namespace {

Expand Down Expand Up @@ -106,42 +101,12 @@ MStatus PRTMaterialNode::compute(const MPlug& plug, MDataBlock& block) {
MStatus stat;

MString meshName;
bool meshFound = false;
bool searchEnded = false;

for (MPlug curPlug = plug; !searchEnded;) {
searchEnded = true;
MPlugArray connectedPlugs;
curPlug.connectedTo(connectedPlugs, false, true, &status);
MCHECK(status);
if (!connectedPlugs.length()) {
return MStatus::kFailure;
}
for (const auto& connectedPlug : mu::makeMArrayConstWrapper(connectedPlugs)) {
MFnDependencyNode connectedDepNode(connectedPlug.node(), &status);
MCHECK(status);
MObject connectedDepNodeObj = connectedDepNode.object(&status);
MCHECK(status);
if (connectedDepNodeObj.hasFn(MFn::kMesh)) {
meshName = connectedDepNode.name(&status);
MCHECK(status);
meshFound = true;
break;
}
if (connectedDepNodeObj.hasFn(MFn::kGroupParts)) {
curPlug = connectedDepNode.findPlug("outputGeometry", true, &status);
MCHECK(status);
searchEnded = false;
break;
}
}
}

if (!meshFound) {
return MStatus::kSuccess;
MStatus meshNameStatus = MaterialUtils::getMeshName(meshName, plug);
if (meshNameStatus != MStatus::kSuccess || meshName.length() == 0) {
return meshNameStatus;
}

if ((inputAssociations != nullptr) && meshFound) {
if ((inputAssociations != nullptr)) {
adsk::Data::Associations outputAssociations(inputMesh.metadata(&status));
MCHECK(status);

Expand Down
9 changes: 2 additions & 7 deletions src/serlio/prtMaterial/PRTMaterialNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,14 @@

#pragma once

#include "PRTContext.h"
#include "prtModifier/MayaCallbacks.h"

#include "maya/MPxNode.h"
#include "maya/MString.h"
#include "maya/adskDataHandle.h"

#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <array>

class MaterialColor;
struct PRTContext;

class PRTMaterialNode : public MPxNode {
public:
Expand Down
1 change: 0 additions & 1 deletion src/serlio/prtModifier/PRTModifierNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#include "prtModifier/PRTModifierNode.h"

#include "util/MayaUtilities.h"
#include "util/Utilities.h"

#include "serlioPlugin.h"

Expand Down
Loading

0 comments on commit efac535

Please sign in to comment.