diff --git a/third_party/maya/lib/usdMaya/CMakeLists.txt b/third_party/maya/lib/usdMaya/CMakeLists.txt index c57d5353b4..e5d478fc01 100644 --- a/third_party/maya/lib/usdMaya/CMakeLists.txt +++ b/third_party/maya/lib/usdMaya/CMakeLists.txt @@ -50,6 +50,7 @@ pxr_shared_library(${PXR_PACKAGE} translatorUtil translatorXformable shadingModeExporter + shadingModeExporterContext shadingModeImporter shadingModeRegistry util diff --git a/third_party/maya/lib/usdMaya/shadingModeDisplayColor.cpp b/third_party/maya/lib/usdMaya/shadingModeDisplayColor.cpp index 4e34cae4bf..c27ba78faa 100644 --- a/third_party/maya/lib/usdMaya/shadingModeDisplayColor.cpp +++ b/third_party/maya/lib/usdMaya/shadingModeDisplayColor.cpp @@ -56,138 +56,151 @@ TF_DEFINE_PRIVATE_TOKENS( ((MayaShaderName, "lambert")) ); +namespace { +class DisplayColorShadingModeExporter : public PxrUsdMayaShadingModeExporter { +public: + DisplayColorShadingModeExporter() {} +private: + void Export(const PxrUsdMayaShadingModeExportContext& context) override { + MStatus status; + MFnDependencyNode ssDepNode(context.GetSurfaceShader(), &status); + if (!status) { + return; + } + MFnLambertShader lambertFn(ssDepNode.object(), &status ); + if (!status) { + return; + } -DEFINE_SHADING_MODE_EXPORTER(displayColor, context) -{ - MStatus status; - MFnDependencyNode ssDepNode(context->GetSurfaceShader(), &status); - if (!status) { - return; - } - MFnLambertShader lambertFn(ssDepNode.object(), &status ); - if (!status) { - return; - } - - const PxrUsdMayaShadingModeExportContext::AssignmentVector& assignments = - context->GetAssignments(); - if (assignments.empty()) { - return; - } + const PxrUsdMayaShadingModeExportContext::AssignmentVector& assignments = + context.GetAssignments(); + if (assignments.empty()) { + return; + } - const UsdStageRefPtr& stage = context->GetUsdStage(); - MColor mayaColor = lambertFn.color(); - MColor mayaTransparency = lambertFn.transparency(); - GfVec3f color = GfConvertDisplayToLinear( + const UsdStageRefPtr& stage = context.GetUsdStage(); + MColor mayaColor = lambertFn.color(); + MColor mayaTransparency = lambertFn.transparency(); + GfVec3f color = GfConvertDisplayToLinear( GfVec3f(mayaColor[0], mayaColor[1], mayaColor[2])); - GfVec3f transparency = GfConvertDisplayToLinear( - GfVec3f(mayaTransparency[0], mayaTransparency[1], mayaTransparency[2])); - - VtArray displayColorAry; - displayColorAry.push_back(color); - - // The simple UsdGeomGprim display shading schema only allows for a - // scalar opacity. We compute it as the unweighted average of the - // components since it would be ridiculous to apply the inverse weighting - // (of the common graycale conversion) on re-import - // The average is compute from the Maya color as is - VtArray displayOpacityAry; - float transparencyAvg = (mayaTransparency[0] + - mayaTransparency[1] + - mayaTransparency[2]) / 3.0; - if (transparencyAvg > 0){ - displayOpacityAry.push_back(1.0 - transparencyAvg); - } - - TF_FOR_ALL(iter, assignments) { - const SdfPath &boundPrimPath = iter->first; - const VtIntArray &faceIndices = iter->second; - if (!faceIndices.empty()) - continue; - - UsdPrim boundPrim = stage->GetPrimAtPath(boundPrimPath); - if (boundPrim) { - UsdGeomGprim primSchema(boundPrim); - // Set color if not already authored - // - // XXX: Note that this will not update the display color - // in the presence of a SdfValueBlock which is a valid - // 'authored value opinion' in the eyes of Usd. - if (!primSchema.GetDisplayColorAttr() - .HasAuthoredValueOpinion()) { - // not animatable - primSchema.GetDisplayColorPrimvar().Set(displayColorAry); - } - if (transparencyAvg > 0 && - !primSchema.GetDisplayOpacityAttr() - .HasAuthoredValueOpinion()) { - // not animatable - primSchema.GetDisplayOpacityPrimvar().Set(displayOpacityAry); + GfVec3f transparency = GfConvertDisplayToLinear( + GfVec3f(mayaTransparency[0], mayaTransparency[1], mayaTransparency[2])); + + VtArray displayColorAry; + displayColorAry.push_back(color); + + // The simple UsdGeomGprim display shading schema only allows for a + // scalar opacity. We compute it as the unweighted average of the + // components since it would be ridiculous to apply the inverse weighting + // (of the common graycale conversion) on re-import + // The average is compute from the Maya color as is + VtArray displayOpacityAry; + float transparencyAvg = (mayaTransparency[0] + + mayaTransparency[1] + + mayaTransparency[2]) / 3.0; + if (transparencyAvg > 0){ + displayOpacityAry.push_back(1.0 - transparencyAvg); + } + + TF_FOR_ALL(iter, assignments) { + const SdfPath &boundPrimPath = iter->first; + const VtIntArray &faceIndices = iter->second; + if (!faceIndices.empty()) + continue; + + UsdPrim boundPrim = stage->GetPrimAtPath(boundPrimPath); + if (boundPrim) { + UsdGeomGprim primSchema(boundPrim); + // Set color if not already authored + // + // XXX: Note that this will not update the display color + // in the presence of a SdfValueBlock which is a valid + // 'authored value opinion' in the eyes of Usd. + if (!primSchema.GetDisplayColorAttr() + .HasAuthoredValueOpinion()) { + // not animatable + primSchema.GetDisplayColorPrimvar().Set(displayColorAry); + } + if (transparencyAvg > 0 && + !primSchema.GetDisplayOpacityAttr() + .HasAuthoredValueOpinion()) { + // not animatable + primSchema.GetDisplayOpacityPrimvar().Set(displayOpacityAry); + } + } else { + MGlobal::displayError("No prim bound to:" + MString(boundPrimPath.GetText())); } - } else { - MGlobal::displayError("No prim bound to:" + MString(boundPrimPath.GetText())); } - } - bool makeMaterialPrim = true; - if (makeMaterialPrim) { - if (UsdShadeMaterial material = - UsdShadeMaterial(context->MakeStandardMaterialPrim(assignments))) { - // Create a Diffuse RIS shader for the Material. - // Although Maya can't yet make use of it, downstream apps - // can make use of Material interface attributes, so create one to - // drive the shader's color. - // - // NOTE! We do not set any values directly on the shaders; - // instead we set the values only on the material's interface, - // emphasizing that the interface is a value provider for - // its shading networks. - UsdShadeInterfaceAttribute dispColorIA = material.CreateInterfaceAttribute( - _tokens->displayColor, + bool makeMaterialPrim = true; + if (makeMaterialPrim) { + if (UsdShadeMaterial material = + UsdShadeMaterial(context.MakeStandardMaterialPrim(assignments))) { + // Create a Diffuse RIS shader for the Material. + // Although Maya can't yet make use of it, downstream apps + // can make use of Material interface attributes, so create one to + // drive the shader's color. + // + // NOTE! We do not set any values directly on the shaders; + // instead we set the values only on the material's interface, + // emphasizing that the interface is a value provider for + // its shading networks. + UsdShadeInterfaceAttribute dispColorIA = material.CreateInterfaceAttribute( + _tokens->displayColor, SdfValueTypeNames->Color3f); - dispColorIA.Set(VtValue(color)); + dispColorIA.Set(VtValue(color)); - UsdPrim materialPrim = material.GetPrim(); - std::string shaderName = TfStringPrintf("%s_lambert", - materialPrim.GetName().GetText()); - TfToken shaderPrimName(shaderName); - UsdRiRisBxdf bxdfSchema = UsdRiRisBxdf::Define( + UsdPrim materialPrim = material.GetPrim(); + std::string shaderName = TfStringPrintf("%s_lambert", + materialPrim.GetName().GetText()); + TfToken shaderPrimName(shaderName); + UsdRiRisBxdf bxdfSchema = UsdRiRisBxdf::Define( stage, materialPrim.GetPath().AppendChild(shaderPrimName)); - bxdfSchema.CreateFilePathAttr(VtValue(SdfAssetPath("PxrDiffuse"))); - UsdShadeParameter diffuse = - bxdfSchema.CreateParameter(_tokens->diffuseColor, - SdfValueTypeNames->Color3f); - UsdRiLookAPI(material).SetInterfaceRecipient(dispColorIA, diffuse); - - - // Make an interface attr for transparency, which we will hook up - // to the shader, and a displayOpacity, for any shader that might - // want to consume it. Only author a *value* if we got a - // non-zero transparency - UsdShadeInterfaceAttribute transparencyIA = - material.CreateInterfaceAttribute(_tokens->transparency, - SdfValueTypeNames->Color3f); - UsdShadeInterfaceAttribute dispOpacityIA = - material.CreateInterfaceAttribute(_tokens->displayOpacity, - SdfValueTypeNames->Float); - - // PxrDiffuse's transmissionColor may not produce similar - // results to MfnLambertShader's transparency, but it's in - // the general ballpark... - UsdShadeParameter transmission = - bxdfSchema.CreateParameter(_tokens->transmissionColor, - SdfValueTypeNames->Color3f); - UsdRiLookAPI(material).SetInterfaceRecipient(transparencyIA, - transmission); - if (transparencyAvg > 0){ - transparencyIA.Set(VtValue(transparency)); - dispOpacityIA.Set(VtValue((float)(1.0-transparencyAvg))); + bxdfSchema.CreateFilePathAttr(VtValue(SdfAssetPath("PxrDiffuse"))); + UsdShadeParameter diffuse = + bxdfSchema.CreateParameter(_tokens->diffuseColor, + SdfValueTypeNames->Color3f); + UsdRiLookAPI(material).SetInterfaceRecipient(dispColorIA, diffuse); + + + // Make an interface attr for transparency, which we will hook up + // to the shader, and a displayOpacity, for any shader that might + // want to consume it. Only author a *value* if we got a + // non-zero transparency + UsdShadeInterfaceAttribute transparencyIA = + material.CreateInterfaceAttribute(_tokens->transparency, + SdfValueTypeNames->Color3f); + UsdShadeInterfaceAttribute dispOpacityIA = + material.CreateInterfaceAttribute(_tokens->displayOpacity, + SdfValueTypeNames->Float); + + // PxrDiffuse's transmissionColor may not produce similar + // results to MfnLambertShader's transparency, but it's in + // the general ballpark... + UsdShadeParameter transmission = + bxdfSchema.CreateParameter(_tokens->transmissionColor, + SdfValueTypeNames->Color3f); + UsdRiLookAPI(material).SetInterfaceRecipient(transparencyIA, + transmission); + if (transparencyAvg > 0){ + transparencyIA.Set(VtValue(transparency)); + dispOpacityIA.Set(VtValue((float)(1.0-transparencyAvg))); + } } } } +}; +} + +TF_REGISTRY_FUNCTION_WITH_TAG(PxrUsdMayaShadingModeExportContext, displayColor) +{ + PxrUsdMayaShadingModeRegistry::GetInstance().RegisterExporter("displayColor", []() -> PxrUsdMayaShadingModeExporterPtr { + return PxrUsdMayaShadingModeExporterPtr( + static_cast(new DisplayColorShadingModeExporter())); + }); } - + DEFINE_SHADING_MODE_IMPORTER(displayColor, context) { const UsdShadeMaterial& shadeMaterial = context->GetShadeMaterial(); diff --git a/third_party/maya/lib/usdMaya/shadingModeExporter.cpp b/third_party/maya/lib/usdMaya/shadingModeExporter.cpp index 4f4ce1a47d..4338f6a421 100644 --- a/third_party/maya/lib/usdMaya/shadingModeExporter.cpp +++ b/third_party/maya/lib/usdMaya/shadingModeExporter.cpp @@ -21,244 +21,44 @@ // KIND, either express or implied. See the Apache License for the specific // language governing permissions and limitations under the Apache License. // -#include "pxr/pxr.h" #include "usdMaya/shadingModeExporter.h" -#include "usdMaya/util.h" - -#include "pxr/usd/usd/prim.h" -#include "pxr/usd/usdGeom/scope.h" -#include "pxr/usd/usdShade/material.h" -#include "pxr/usd/usdShade/parameter.h" -#include "pxr/usd/usdShade/shader.h" - -#include -#include -#include -#include -#include -#include +#include PXR_NAMESPACE_OPEN_SCOPE +PxrUsdMayaShadingModeExporter::PxrUsdMayaShadingModeExporter() { - -PxrUsdMayaShadingModeExportContext::PxrUsdMayaShadingModeExportContext( - const MObject& shadingEngine, - const UsdStageRefPtr& stage, - bool mergeTransformAndShape, - const PxrUsdMayaUtil::ShapeSet& bindableRoots, - SdfPath overrideRootPath) : - _shadingEngine(shadingEngine), - _stage(stage), - _mergeTransformAndShape(mergeTransformAndShape), - _overrideRootPath(overrideRootPath) -{ - if (bindableRoots.empty()) { - // if none specified, push back '/' which encompasses all - _bindableRoots.insert(SdfPath::AbsoluteRootPath()); - } - else { - TF_FOR_ALL(bindableRootIter, bindableRoots) { - const MDagPath& bindableRootDagPath = *bindableRootIter; - - - SdfPath usdPath = PxrUsdMayaUtil::MDagPathToUsdPath(bindableRootDagPath, - _mergeTransformAndShape); - - // If _overrideRootPath is not empty, replace the root namespace with it - if (!_overrideRootPath.IsEmpty() ) { - usdPath = usdPath.ReplacePrefix(usdPath.GetPrefixes()[0], _overrideRootPath); - } - - _bindableRoots.insert(usdPath); - } - } } -MObject -PxrUsdMayaShadingModeExportContext::GetSurfaceShader() const -{ - MStatus status; - MFnDependencyNode seDepNode(_shadingEngine, &status); - if (!status) { - return MObject(); - } - - MPlug ssPlug = seDepNode.findPlug("surfaceShader", true, &status); - if (!status) { - return MObject(); - } - - MObject ss(ssPlug.asMObject()); - if (ss.isNull()) { - return MObject(); - } +PxrUsdMayaShadingModeExporter::~PxrUsdMayaShadingModeExporter() { - return PxrUsdMayaUtil::GetConnected(ssPlug).node(); } -PxrUsdMayaShadingModeExportContext::AssignmentVector -PxrUsdMayaShadingModeExportContext::GetAssignments() const -{ - AssignmentVector ret; - - MStatus status; - MFnDependencyNode seDepNode(_shadingEngine, &status); - if (!status) { - return ret; +void +PxrUsdMayaShadingModeExporter::DoExport( + const UsdStageRefPtr& stage, + const PxrUsdMayaUtil::ShapeSet& bindableRoots, + bool mergeTransformAndShape, + const SdfPath& overrideRootPath) { + MItDependencyNodes shadingEngineIter(MFn::kShadingEngine); + for (; !shadingEngineIter.isDone(); shadingEngineIter.next()) { + MObject shadingEngine(shadingEngineIter.thisNode()); + + PxrUsdMayaShadingModeExportContext c( + shadingEngine, + stage, + mergeTransformAndShape, + bindableRoots, + overrideRootPath); + + Export(c); } - - MPlug dsmPlug = seDepNode.findPlug("dagSetMembers", true, &status); - if (!status) { - return ret; - } - - SdfPathSet seenBoundPrimPaths; - for (unsigned int i = 0; i < dsmPlug.numConnectedElements(); i++) { - MPlug dsmElemPlug(dsmPlug.connectionByPhysicalIndex(i)); - MStatus status = MS::kFailure; - MFnDagNode dagNode(PxrUsdMayaUtil::GetConnected(dsmElemPlug).node(), &status); - if (!status) { - continue; - } - - MDagPath dagPath; - if (!dagNode.getPath(dagPath)) - continue; - - SdfPath usdPath = PxrUsdMayaUtil::MDagPathToUsdPath(dagPath, - _mergeTransformAndShape); - - // If _overrideRootPath is not empty, replace the root namespace with it - if (!_overrideRootPath.IsEmpty() ) { - usdPath = usdPath.ReplacePrefix(usdPath.GetPrefixes()[0], _overrideRootPath); - } - - // If this path has already been processed, skip it. - if (!seenBoundPrimPaths.insert(usdPath).second) - continue; - - // If the bound prim's path is not below a bindable root, skip it. - if (SdfPathFindLongestPrefix(_bindableRoots.begin(), - _bindableRoots.end(), usdPath) == _bindableRoots.end()) { - continue; - } - - MObjectArray sgObjs, compObjs; - // Assuming that instancing is not involved. - status = dagNode.getConnectedSetsAndMembers(0, sgObjs, compObjs, true); - if (!status) - continue; - - for (size_t j = 0; j < sgObjs.length(); j++) { - // If the shading group isn't the one we're interested in, skip it. - if (sgObjs[j] != _shadingEngine) - continue; - - VtIntArray faceIndices; - if (!compObjs[j].isNull()) { - MItMeshPolygon faceIt(dagPath, compObjs[j]); - faceIndices.reserve(faceIt.count()); - for ( faceIt.reset() ; !faceIt.isDone() ; faceIt.next() ) { - faceIndices.push_back(faceIt.index()); - } - } - ret.push_back(std::make_pair(usdPath, faceIndices)); - } - } - return ret; } -static UsdPrim -_GetMaterialParent(const UsdStageRefPtr& stage, - const PxrUsdMayaShadingModeExportContext::AssignmentVector& assignments) -{ - SdfPath commonAncestor; - TF_FOR_ALL(iter, assignments) { - const SdfPath& assn = iter->first; - if (stage->GetPrimAtPath(assn)) { - if (commonAncestor.IsEmpty()) { - commonAncestor = assn; - } - else { - commonAncestor = commonAncestor.GetCommonPrefix(assn); - } - } - } - - if (commonAncestor.IsEmpty()) { - return UsdPrim(); - } - - if (commonAncestor == SdfPath::AbsoluteRootPath()) { - return stage->GetPseudoRoot(); - } - - SdfPath shaderExportLocation = commonAncestor; - while (!shaderExportLocation.IsRootPrimPath()) { - shaderExportLocation = shaderExportLocation.GetParentPath(); - } - shaderExportLocation = shaderExportLocation.AppendChild(TfToken("Looks")); +void +PxrUsdMayaShadingModeExporter::Export(const PxrUsdMayaShadingModeExportContext& ctx) { - return UsdGeomScope::Define(stage, shaderExportLocation).GetPrim(); -} - -UsdPrim -PxrUsdMayaShadingModeExportContext::MakeStandardMaterialPrim( - const AssignmentVector& assignmentsToBind, - const std::string& name) const -{ - UsdPrim ret; - - std::string materialName = name; - if (materialName.empty()) { - MStatus status; - MFnDependencyNode seDepNode(_shadingEngine, &status); - if (!status) { - return ret; - } - MString seName = seDepNode.name(); - materialName = MNamespace::stripNamespaceFromName(seName).asChar(); - } - - materialName = PxrUsdMayaUtil::SanitizeName(materialName); - UsdStageRefPtr stage = GetUsdStage(); - if (UsdPrim materialParent = _GetMaterialParent(stage, assignmentsToBind)) { - SdfPath materialPath = materialParent.GetPath().AppendChild( - TfToken(materialName)); - UsdShadeMaterial material = UsdShadeMaterial::Define( - GetUsdStage(), materialPath); - - UsdPrim materialPrim = material.GetPrim(); - - // could use this to determine where we want to export. whatever. - TF_FOR_ALL(iter, assignmentsToBind) { - const SdfPath &boundPrimPath = iter->first; - const VtIntArray &faceIndices = iter->second; - - UsdPrim boundPrim = stage->OverridePrim(boundPrimPath); - if (faceIndices.empty()) { - material.Bind(boundPrim); - } else { - UsdGeomFaceSetAPI faceSet = material.CreateMaterialFaceSet( - boundPrim); - faceSet.AppendFaceGroup(faceIndices, materialPath); - } - } - - return materialPrim; - } - - return UsdPrim(); -} - -std::string -PxrUsdMayaShadingModeExportContext::GetStandardAttrName(const MPlug& attrPlug) const -{ - MString mayaPlgName = attrPlug.partialName(false, false, false, false, false, true); - return mayaPlgName.asChar(); } PXR_NAMESPACE_CLOSE_SCOPE - diff --git a/third_party/maya/lib/usdMaya/shadingModeExporter.h b/third_party/maya/lib/usdMaya/shadingModeExporter.h index 7a52383869..fd45295056 100644 --- a/third_party/maya/lib/usdMaya/shadingModeExporter.h +++ b/third_party/maya/lib/usdMaya/shadingModeExporter.h @@ -21,72 +21,34 @@ // KIND, either express or implied. See the Apache License for the specific // language governing permissions and limitations under the Apache License. // + #ifndef PXRUSDMAYA_SHADINGMODEEXPORTER_H #define PXRUSDMAYA_SHADINGMODEEXPORTER_H #include "pxr/pxr.h" -#include "usdMaya/util.h" -#include "pxr/usd/usd/stage.h" +#include "usdMaya/shadingModeExporterContext.h" -#include -#include +#include +#include PXR_NAMESPACE_OPEN_SCOPE - -class PxrUsdMayaShadingModeExportContext -{ +class PxrUsdMayaShadingModeExporter { public: - MObject GetShadingEngine() const { return _shadingEngine; } - const UsdStageRefPtr& GetUsdStage() const { return _stage; } - - MObject GetSurfaceShader() const; - - /// An assignment contains a bound prim path and a list of faceIndices. - /// If the list of faceIndices is non-empty, then it is a partial assignment - /// targeting a subset of the bound prim's faces. - /// If the list of faceIndices is empty, it means the assignment targets - /// all the faces in the bound prim or the entire bound prim. - typedef std::pair Assignment; - - /// Vector of assignments. - typedef std::vector AssignmentVector; - - /// Returns a vector of binding assignments associated with the shading - /// engine. - AssignmentVector GetAssignments() const; + PxrUsdMayaShadingModeExporter(); + virtual ~PxrUsdMayaShadingModeExporter(); - /// Use this function to create a UsdShadeMaterial prim at the "standard" - /// location. The "standard" location may change depending on arguments - /// that are passed to the export script. - UsdPrim MakeStandardMaterialPrim( - const AssignmentVector& assignmentsToBind, - const std::string& name=std::string()) const; + virtual void DoExport(const UsdStageRefPtr& stage, + const PxrUsdMayaUtil::ShapeSet& bindableRoots, + bool mergeTransformAndShape, + const SdfPath& overrideRootPath); - /// Use this function to get a "standard" usd attr name for \p attrPlug. - /// The definition of "standard" may depend on arguments passed to the - /// script (i.e. stripping namespaces, etc.). - std::string GetStandardAttrName(const MPlug& attrPlug) const; - - PxrUsdMayaShadingModeExportContext( - const MObject& shadingEngine, - const UsdStageRefPtr& stage, - bool mergeTransformAndShape, - const PxrUsdMayaUtil::ShapeSet& bindableRoots, - SdfPath overrideRootPath); - -private: - MObject _shadingEngine; - const UsdStageRefPtr& _stage; - bool _mergeTransformAndShape; - SdfPath _overrideRootPath; - - SdfPathSet _bindableRoots; + virtual void Export(const PxrUsdMayaShadingModeExportContext& context); }; -typedef boost::function< void (PxrUsdMayaShadingModeExportContext*) > PxrUsdMayaShadingModeExporter; - +using PxrUsdMayaShadingModeExporterPtr = std::shared_ptr; +using PxrUsdMayaShadingModeExporterCreator = std::function()>; PXR_NAMESPACE_CLOSE_SCOPE diff --git a/third_party/maya/lib/usdMaya/shadingModeExporterContext.cpp b/third_party/maya/lib/usdMaya/shadingModeExporterContext.cpp new file mode 100644 index 0000000000..e1fa2da05a --- /dev/null +++ b/third_party/maya/lib/usdMaya/shadingModeExporterContext.cpp @@ -0,0 +1,264 @@ +// +// Copyright 2016 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +#include "pxr/pxr.h" +#include "usdMaya/shadingModeExporterContext.h" + +#include "usdMaya/util.h" + +#include "pxr/usd/usd/prim.h" +#include "pxr/usd/usdGeom/scope.h" +#include "pxr/usd/usdShade/material.h" +#include "pxr/usd/usdShade/parameter.h" +#include "pxr/usd/usdShade/shader.h" + +#include +#include +#include +#include +#include +#include + +PXR_NAMESPACE_OPEN_SCOPE + + + +PxrUsdMayaShadingModeExportContext::PxrUsdMayaShadingModeExportContext( + const MObject& shadingEngine, + const UsdStageRefPtr& stage, + bool mergeTransformAndShape, + const PxrUsdMayaUtil::ShapeSet& bindableRoots, + SdfPath overrideRootPath) : + _shadingEngine(shadingEngine), + _stage(stage), + _mergeTransformAndShape(mergeTransformAndShape), + _overrideRootPath(overrideRootPath) +{ + if (bindableRoots.empty()) { + // if none specified, push back '/' which encompasses all + _bindableRoots.insert(SdfPath::AbsoluteRootPath()); + } + else { + TF_FOR_ALL(bindableRootIter, bindableRoots) { + const MDagPath& bindableRootDagPath = *bindableRootIter; + + + SdfPath usdPath = PxrUsdMayaUtil::MDagPathToUsdPath(bindableRootDagPath, + _mergeTransformAndShape); + + // If _overrideRootPath is not empty, replace the root namespace with it + if (!_overrideRootPath.IsEmpty() ) { + usdPath = usdPath.ReplacePrefix(usdPath.GetPrefixes()[0], _overrideRootPath); + } + + _bindableRoots.insert(usdPath); + } + } +} + +MObject +PxrUsdMayaShadingModeExportContext::GetSurfaceShader() const +{ + MStatus status; + MFnDependencyNode seDepNode(_shadingEngine, &status); + if (!status) { + return MObject(); + } + + MPlug ssPlug = seDepNode.findPlug("surfaceShader", true, &status); + if (!status) { + return MObject(); + } + + MObject ss(ssPlug.asMObject()); + if (ss.isNull()) { + return MObject(); + } + + return PxrUsdMayaUtil::GetConnected(ssPlug).node(); +} + +PxrUsdMayaShadingModeExportContext::AssignmentVector +PxrUsdMayaShadingModeExportContext::GetAssignments() const +{ + AssignmentVector ret; + + MStatus status; + MFnDependencyNode seDepNode(_shadingEngine, &status); + if (!status) { + return ret; + } + + MPlug dsmPlug = seDepNode.findPlug("dagSetMembers", true, &status); + if (!status) { + return ret; + } + + SdfPathSet seenBoundPrimPaths; + for (unsigned int i = 0; i < dsmPlug.numConnectedElements(); i++) { + MPlug dsmElemPlug(dsmPlug.connectionByPhysicalIndex(i)); + MStatus status = MS::kFailure; + MFnDagNode dagNode(PxrUsdMayaUtil::GetConnected(dsmElemPlug).node(), &status); + if (!status) { + continue; + } + + MDagPath dagPath; + if (!dagNode.getPath(dagPath)) + continue; + + SdfPath usdPath = PxrUsdMayaUtil::MDagPathToUsdPath(dagPath, + _mergeTransformAndShape); + + // If _overrideRootPath is not empty, replace the root namespace with it + if (!_overrideRootPath.IsEmpty() ) { + usdPath = usdPath.ReplacePrefix(usdPath.GetPrefixes()[0], _overrideRootPath); + } + + // If this path has already been processed, skip it. + if (!seenBoundPrimPaths.insert(usdPath).second) + continue; + + // If the bound prim's path is not below a bindable root, skip it. + if (SdfPathFindLongestPrefix(_bindableRoots.begin(), + _bindableRoots.end(), usdPath) == _bindableRoots.end()) { + continue; + } + + MObjectArray sgObjs, compObjs; + // Assuming that instancing is not involved. + status = dagNode.getConnectedSetsAndMembers(0, sgObjs, compObjs, true); + if (!status) + continue; + + for (size_t j = 0; j < sgObjs.length(); j++) { + // If the shading group isn't the one we're interested in, skip it. + if (sgObjs[j] != _shadingEngine) + continue; + + VtIntArray faceIndices; + if (!compObjs[j].isNull()) { + MItMeshPolygon faceIt(dagPath, compObjs[j]); + faceIndices.reserve(faceIt.count()); + for ( faceIt.reset() ; !faceIt.isDone() ; faceIt.next() ) { + faceIndices.push_back(faceIt.index()); + } + } + ret.push_back(std::make_pair(usdPath, faceIndices)); + } + } + return ret; +} + +static UsdPrim +_GetMaterialParent(const UsdStageRefPtr& stage, + const PxrUsdMayaShadingModeExportContext::AssignmentVector& assignments) +{ + SdfPath commonAncestor; + TF_FOR_ALL(iter, assignments) { + const SdfPath& assn = iter->first; + if (stage->GetPrimAtPath(assn)) { + if (commonAncestor.IsEmpty()) { + commonAncestor = assn; + } + else { + commonAncestor = commonAncestor.GetCommonPrefix(assn); + } + } + } + + if (commonAncestor.IsEmpty()) { + return UsdPrim(); + } + + if (commonAncestor == SdfPath::AbsoluteRootPath()) { + return stage->GetPseudoRoot(); + } + + SdfPath shaderExportLocation = commonAncestor; + while (!shaderExportLocation.IsRootPrimPath()) { + shaderExportLocation = shaderExportLocation.GetParentPath(); + } + shaderExportLocation = shaderExportLocation.AppendChild(TfToken("Looks")); + + return UsdGeomScope::Define(stage, shaderExportLocation).GetPrim(); +} + +UsdPrim +PxrUsdMayaShadingModeExportContext::MakeStandardMaterialPrim( + const AssignmentVector& assignmentsToBind, + const std::string& name) const +{ + UsdPrim ret; + + std::string materialName = name; + if (materialName.empty()) { + MStatus status; + MFnDependencyNode seDepNode(_shadingEngine, &status); + if (!status) { + return ret; + } + MString seName = seDepNode.name(); + materialName = MNamespace::stripNamespaceFromName(seName).asChar(); + } + + materialName = PxrUsdMayaUtil::SanitizeName(materialName); + UsdStageRefPtr stage = GetUsdStage(); + if (UsdPrim materialParent = _GetMaterialParent(stage, assignmentsToBind)) { + SdfPath materialPath = materialParent.GetPath().AppendChild( + TfToken(materialName)); + UsdShadeMaterial material = UsdShadeMaterial::Define( + GetUsdStage(), materialPath); + + UsdPrim materialPrim = material.GetPrim(); + + // could use this to determine where we want to export. whatever. + TF_FOR_ALL(iter, assignmentsToBind) { + const SdfPath &boundPrimPath = iter->first; + const VtIntArray &faceIndices = iter->second; + + UsdPrim boundPrim = stage->OverridePrim(boundPrimPath); + if (faceIndices.empty()) { + material.Bind(boundPrim); + } else { + UsdGeomFaceSetAPI faceSet = material.CreateMaterialFaceSet( + boundPrim); + faceSet.AppendFaceGroup(faceIndices, materialPath); + } + } + + return materialPrim; + } + + return UsdPrim(); +} + +std::string +PxrUsdMayaShadingModeExportContext::GetStandardAttrName(const MPlug& attrPlug) const +{ + MString mayaPlgName = attrPlug.partialName(false, false, false, false, false, true); + return mayaPlgName.asChar(); +} + +PXR_NAMESPACE_CLOSE_SCOPE + diff --git a/third_party/maya/lib/usdMaya/shadingModeExporterContext.h b/third_party/maya/lib/usdMaya/shadingModeExporterContext.h new file mode 100644 index 0000000000..6b7a593990 --- /dev/null +++ b/third_party/maya/lib/usdMaya/shadingModeExporterContext.h @@ -0,0 +1,88 @@ +// +// Copyright 2016 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// +#ifndef PXRUSDMAYA_SHADINGMODEEXPORTERCONTEXT_H +#define PXRUSDMAYA_SHADINGMODEEXPORTERCONTEXT_H + +#include "pxr/pxr.h" +#include "usdMaya/util.h" +#include "pxr/usd/usd/stage.h" + + +#include + +PXR_NAMESPACE_OPEN_SCOPE + +class PxrUsdMayaShadingModeExportContext +{ +public: + MObject GetShadingEngine() const { return _shadingEngine; } + const UsdStageRefPtr& GetUsdStage() const { return _stage; } + + MObject GetSurfaceShader() const; + + /// An assignment contains a bound prim path and a list of faceIndices. + /// If the list of faceIndices is non-empty, then it is a partial assignment + /// targeting a subset of the bound prim's faces. + /// If the list of faceIndices is empty, it means the assignment targets + /// all the faces in the bound prim or the entire bound prim. + typedef std::pair Assignment; + + /// Vector of assignments. + typedef std::vector AssignmentVector; + + /// Returns a vector of binding assignments associated with the shading + /// engine. + AssignmentVector GetAssignments() const; + + /// Use this function to create a UsdShadeMaterial prim at the "standard" + /// location. The "standard" location may change depending on arguments + /// that are passed to the export script. + UsdPrim MakeStandardMaterialPrim( + const AssignmentVector& assignmentsToBind, + const std::string& name=std::string()) const; + + /// Use this function to get a "standard" usd attr name for \p attrPlug. + /// The definition of "standard" may depend on arguments passed to the + /// script (i.e. stripping namespaces, etc.). + std::string GetStandardAttrName(const MPlug& attrPlug) const; + + PxrUsdMayaShadingModeExportContext( + const MObject& shadingEngine, + const UsdStageRefPtr& stage, + bool mergeTransformAndShape, + const PxrUsdMayaUtil::ShapeSet& bindableRoots, + SdfPath overrideRootPath); +private: + MObject _shadingEngine; + const UsdStageRefPtr& _stage; + bool _mergeTransformAndShape; + bool _handleUsdNamespaces; + SdfPath _overrideRootPath; + + SdfPathSet _bindableRoots; +}; + +PXR_NAMESPACE_CLOSE_SCOPE + +#endif // PXRUSDMAYA_SHADINGMODEEXPORTERCONTEXT_H diff --git a/third_party/maya/lib/usdMaya/shadingModePxrRis.cpp b/third_party/maya/lib/usdMaya/shadingModePxrRis.cpp index 60feee53fc..bf1764dc94 100644 --- a/third_party/maya/lib/usdMaya/shadingModePxrRis.cpp +++ b/third_party/maya/lib/usdMaya/shadingModePxrRis.cpp @@ -27,6 +27,7 @@ #include "usdMaya/shadingModeRegistry.h" #include "usdMaya/shadingModeExporter.h" +#include "usdMaya/shadingModeExporterContext.h" #include "pxr/usd/usd/prim.h" @@ -51,152 +52,161 @@ PXR_NAMESPACE_OPEN_SCOPE -namespace _exporter { - -static std::string -_GetShaderTypeName(const MFnDependencyNode& depNode) -{ - std::string risShaderType(depNode.typeName().asChar()); - // Now look into the RIS TABLE if the typeName doesn't starts with Pxr - if (!TfStringStartsWith(risShaderType, "Pxr")) { - for (size_t i=0;i<_RFM_RISNODE_TABLE.size();i++) { - if (_RFM_RISNODE_TABLE[i].first==risShaderType) { - risShaderType=_RFM_RISNODE_TABLE[i].second; - break; +namespace { +class PxrRisShadingModeExporter : public PxrUsdMayaShadingModeExporter { +public: + PxrRisShadingModeExporter() {} +private: + std::string + _GetShaderTypeName(const MFnDependencyNode& depNode) + { + std::string risShaderType(depNode.typeName().asChar()); + // Now look into the RIS TABLE if the typeName doesn't starts with Pxr + if (!TfStringStartsWith(risShaderType, "Pxr")) { + for (size_t i=0;i<_RFM_RISNODE_TABLE.size();i++) { + if (_RFM_RISNODE_TABLE[i].first==risShaderType) { + risShaderType=_RFM_RISNODE_TABLE[i].second; + break; + } } } + return risShaderType; } - return risShaderType; -} -static UsdPrim -_ExportShadingNode(const UsdPrim& materialPrim, - const MFnDependencyNode& depNode, - const PxrUsdMayaShadingModeExportContext* context, - SdfPathSet *processedPaths, - bool isFirstNode -) -{ - UsdStagePtr stage = materialPrim.GetStage(); + UsdPrim + _ExportShadingNode(const UsdPrim& materialPrim, + const MFnDependencyNode& depNode, + const PxrUsdMayaShadingModeExportContext& context, + SdfPathSet *processedPaths, + bool isFirstNode + ) + { + UsdStagePtr stage = materialPrim.GetStage(); + + // XXX: would be nice to write out the current display color as + // well. currently, when we re-import, we don't get the display color so + // it shows up as black. + + TfToken shaderPrimName(PxrUsdMayaUtil::SanitizeName(depNode.name().asChar())); + SdfPath shaderPath = materialPrim.GetPath().AppendChild(shaderPrimName); + if (processedPaths->count(shaderPath) == 1){ + return stage->GetPrimAtPath(shaderPath); + } - // XXX: would be nice to write out the current display color as - // well. currently, when we re-import, we don't get the display color so - // it shows up as black. + processedPaths->insert(shaderPath); - TfToken shaderPrimName(PxrUsdMayaUtil::SanitizeName(depNode.name().asChar())); - SdfPath shaderPath = materialPrim.GetPath().AppendChild(shaderPrimName); - if (processedPaths->count(shaderPath) == 1){ - return stage->GetPrimAtPath(shaderPath); - } + // Determie the risShaderType that will correspont to the USD FilePath + std::string risShaderType(_GetShaderTypeName(depNode)); - processedPaths->insert(shaderPath); - - // Determie the risShaderType that will correspont to the USD FilePath - std::string risShaderType(_GetShaderTypeName(depNode)); - - if (!TfStringStartsWith(risShaderType, "Pxr")) { - MGlobal::displayError(TfStringPrintf( + if (!TfStringStartsWith(risShaderType, "Pxr")) { + MGlobal::displayError(TfStringPrintf( "_ExportShadingNode: skipping '%s' because it's type '%s' is not Pxr.\n", depNode.name().asChar(), risShaderType.c_str()).c_str()); - return UsdPrim(); - } - - // The first node is the Bxdf, subsequent ones are Pattern objects - UsdRiRisObject risObj; - if (isFirstNode) - risObj = UsdRiRisBxdf::Define(stage, shaderPath); - else - risObj = UsdRiRisPattern::Define(stage, shaderPath); + return UsdPrim(); + } - risObj.CreateFilePathAttr(VtValue(SdfAssetPath(risShaderType))); + // The first node is the Bxdf, subsequent ones are Pattern objects + UsdRiRisObject risObj; + if (isFirstNode) + risObj = UsdRiRisBxdf::Define(stage, shaderPath); + else + risObj = UsdRiRisPattern::Define(stage, shaderPath); - MStatus status = MS::kFailure; - - for (unsigned int i = 0; i < depNode.attributeCount(); i++) { - MPlug attrPlug = depNode.findPlug(depNode.attribute(i), true); - if (attrPlug.isProcedural()) { - // maya docs says these should not be saved off. we skip them - // here. - continue; - } + risObj.CreateFilePathAttr(VtValue(SdfAssetPath(risShaderType))); - if (attrPlug.isChild()) { - continue; - } + MStatus status = MS::kFailure; - // this is writing out things that live on the MFnDependencyNode. - // maybe that's OK? nothing downstream cares about it. + for (unsigned int i = 0; i < depNode.attributeCount(); i++) { + MPlug attrPlug = depNode.findPlug(depNode.attribute(i), true); + if (attrPlug.isProcedural()) { + // maya docs says these should not be saved off. we skip them + // here. + continue; + } - TfToken attrName = TfToken(context->GetStandardAttrName(attrPlug)); - SdfValueTypeName attrTypeName = PxrUsdMayaWriteUtil::GetUsdTypeName(attrPlug); - if (!attrTypeName) { - // unsupported type - continue; - } + if (attrPlug.isChild()) { + continue; + } - UsdShadeParameter param = risObj.CreateParameter(attrName, attrTypeName); - if (!param) { - continue; - } + // this is writing out things that live on the MFnDependencyNode. + // maybe that's OK? nothing downstream cares about it. + + TfToken attrName = TfToken(context.GetStandardAttrName(attrPlug)); + SdfValueTypeName attrTypeName = PxrUsdMayaWriteUtil::GetUsdTypeName(attrPlug); + if (!attrTypeName) { + // unsupported type + continue; + } - PxrUsdMayaWriteUtil::SetUsdAttr( + UsdShadeParameter param = risObj.CreateParameter(attrName, attrTypeName); + if (!param) { + continue; + } + + PxrUsdMayaWriteUtil::SetUsdAttr( attrPlug, param.GetAttr(), UsdTimeCode::Default()); - if (attrPlug.isConnected() && attrPlug.isDestination()) { - MPlug connected(PxrUsdMayaUtil::GetConnected(attrPlug)); - MFnDependencyNode c(connected.node(), &status); - if (status) { - if (UsdPrim cPrim = _ExportShadingNode(materialPrim, - c, - context, - processedPaths, - false)) { - param.ConnectToSource( - UsdShadeShader(cPrim), - TfToken(context->GetStandardAttrName(connected))); + if (attrPlug.isConnected() && attrPlug.isDestination()) { + MPlug connected(PxrUsdMayaUtil::GetConnected(attrPlug)); + MFnDependencyNode c(connected.node(), &status); + if (status) { + if (UsdPrim cPrim = _ExportShadingNode(materialPrim, + c, + context, + processedPaths, + false)) { + param.ConnectToSource( + UsdShadeShader(cPrim), + TfToken(context.GetStandardAttrName(connected))); + } } } } - } - - return risObj.GetPrim(); -} -}; // namespace _exporter - -DEFINE_SHADING_MODE_EXPORTER(pxrRis, context) -{ - MStatus status; - const PxrUsdMayaShadingModeExportContext::AssignmentVector &assignments = - context->GetAssignments(); - if (assignments.empty()) { - return; + return risObj.GetPrim(); } - UsdPrim materialPrim = context->MakeStandardMaterialPrim(assignments); - if (!materialPrim) { - return; - } + void Export(const PxrUsdMayaShadingModeExportContext& context) override { + MStatus status; + const PxrUsdMayaShadingModeExportContext::AssignmentVector &assignments = + context.GetAssignments(); + if (assignments.empty()) { + return; + } - MFnDependencyNode ssDepNode(context->GetSurfaceShader(), &status); - if (!status) { - return; - } - SdfPathSet processedShaders; - if (UsdPrim shaderPrim = _exporter::_ExportShadingNode(materialPrim, - ssDepNode, - context, - &processedShaders, true)) { - UsdRiLookAPI riLook = UsdRiLookAPI(materialPrim); - std::vector bxdfTargets; - bxdfTargets.push_back(shaderPrim.GetPath()); - riLook.CreateBxdfRel().SetTargets(bxdfTargets); + UsdPrim materialPrim = context.MakeStandardMaterialPrim(assignments); + if (!materialPrim) { + return; + } + + MFnDependencyNode ssDepNode(context.GetSurfaceShader(), &status); + if (!status) { + return; + } + SdfPathSet processedShaders; + if (UsdPrim shaderPrim = _ExportShadingNode(materialPrim, + ssDepNode, + context, + &processedShaders, true)) { + UsdRiLookAPI riLook = UsdRiLookAPI(materialPrim); + std::vector bxdfTargets; + bxdfTargets.push_back(shaderPrim.GetPath()); + riLook.CreateBxdfRel().SetTargets(bxdfTargets); + } } +}; } +TF_REGISTRY_FUNCTION_WITH_TAG(PxrUsdMayaShadingModeExportContext, pxrRis) +{ + PxrUsdMayaShadingModeRegistry::GetInstance().RegisterExporter("pxrRis", []() -> PxrUsdMayaShadingModeExporterPtr { + return PxrUsdMayaShadingModeExporterPtr( + static_cast(new PxrRisShadingModeExporter())); + }); +} namespace _importer { diff --git a/third_party/maya/lib/usdMaya/shadingModeRegistry.cpp b/third_party/maya/lib/usdMaya/shadingModeRegistry.cpp index fbdaa55c32..6089fe96a4 100644 --- a/third_party/maya/lib/usdMaya/shadingModeRegistry.cpp +++ b/third_party/maya/lib/usdMaya/shadingModeRegistry.cpp @@ -31,20 +31,20 @@ PXR_NAMESPACE_OPEN_SCOPE TF_DEFINE_PUBLIC_TOKENS(PxrUsdMayaShadingModeTokens, PXRUSDMAYA_SHADINGMODE_TOKENS); -typedef std::map _ExportRegistry; +typedef std::map _ExportRegistry; static _ExportRegistry _exportReg; bool PxrUsdMayaShadingModeRegistry::RegisterExporter( const std::string& name, - PxrUsdMayaShadingModeExporter fn) + PxrUsdMayaShadingModeExporterCreator fn) { std::pair<_ExportRegistry::const_iterator, bool> insertStatus = _exportReg.insert( std::make_pair(TfToken(name), fn)); return insertStatus.second; } -PxrUsdMayaShadingModeExporter +PxrUsdMayaShadingModeExporterCreator PxrUsdMayaShadingModeRegistry::_GetExporter(const TfToken& name) { TfRegistryManager::GetInstance().SubscribeTo(); diff --git a/third_party/maya/lib/usdMaya/shadingModeRegistry.h b/third_party/maya/lib/usdMaya/shadingModeRegistry.h index e9db4a8dba..ee5b76e7e3 100644 --- a/third_party/maya/lib/usdMaya/shadingModeRegistry.h +++ b/third_party/maya/lib/usdMaya/shadingModeRegistry.h @@ -36,6 +36,7 @@ #include "pxr/pxr.h" #include "usdMaya/shadingModeExporter.h" +#include "usdMaya/shadingModeExporterContext.h" #include "usdMaya/shadingModeImporter.h" #include "pxr/base/tf/registryManager.h" @@ -57,9 +58,8 @@ class PxrUsdMayaShadingModeRegistry : public TfWeakBase { public: - static PxrUsdMayaShadingModeExporter GetExporter(const TfToken& name) { + static PxrUsdMayaShadingModeExporterCreator GetExporter(const TfToken& name) { return GetInstance()._GetExporter(name); - } static PxrUsdMayaShadingModeImporter GetImporter(const TfToken& name) { return GetInstance()._GetImporter(name); @@ -68,14 +68,14 @@ class PxrUsdMayaShadingModeRegistry : public TfWeakBase static PxrUsdMayaShadingModeRegistry& GetInstance(); bool RegisterExporter( const std::string& name, - PxrUsdMayaShadingModeExporter fn); + PxrUsdMayaShadingModeExporterCreator fn); bool RegisterImporter( const std::string& name, PxrUsdMayaShadingModeImporter fn); private: - PxrUsdMayaShadingModeExporter _GetExporter(const TfToken& name); + PxrUsdMayaShadingModeExporterCreator _GetExporter(const TfToken& name); PxrUsdMayaShadingModeImporter _GetImporter(const TfToken& name); PxrUsdMayaShadingModeRegistry(); @@ -83,13 +83,6 @@ class PxrUsdMayaShadingModeRegistry : public TfWeakBase friend class TfSingleton; }; -#define DEFINE_SHADING_MODE_EXPORTER(name, contextName) \ -static void _ShadingModeExporter_##name(PxrUsdMayaShadingModeExportContext*); \ -TF_REGISTRY_FUNCTION_WITH_TAG(PxrUsdMayaShadingModeExportContext, name) {\ - PxrUsdMayaShadingModeRegistry::GetInstance().RegisterExporter(#name, &_ShadingModeExporter_##name); \ -}\ -void _ShadingModeExporter_##name(PxrUsdMayaShadingModeExportContext* contextName) - #define DEFINE_SHADING_MODE_IMPORTER(name, contextName) \ static MPlug _ShadingModeImporter_##name(PxrUsdMayaShadingModeImportContext*); \ TF_REGISTRY_FUNCTION_WITH_TAG(PxrUsdMayaShadingModeImportContext, name) {\ diff --git a/third_party/maya/lib/usdMaya/translatorMaterial.cpp b/third_party/maya/lib/usdMaya/translatorMaterial.cpp index 47ff39a48c..a25fa91ed5 100644 --- a/third_party/maya/lib/usdMaya/translatorMaterial.cpp +++ b/third_party/maya/lib/usdMaya/translatorMaterial.cpp @@ -317,21 +317,10 @@ PxrUsdMayaTranslatorMaterial::ExportShadingEngines( return; } - if (PxrUsdMayaShadingModeExporter exporter = + if (auto exporterCreator = PxrUsdMayaShadingModeRegistry::GetExporter(shadingMode)) { - MItDependencyNodes shadingEngineIter(MFn::kShadingEngine); - for (; !shadingEngineIter.isDone(); shadingEngineIter.next()) { - MObject shadingEngine(shadingEngineIter.thisNode()); - MFnDependencyNode seDepNode(shadingEngine); - - PxrUsdMayaShadingModeExportContext c( - shadingEngine, - stage, - mergeTransformAndShape, - bindableRoots, - overrideRootPath); - - exporter(&c); + if (auto exporter = exporterCreator()) { + exporter->DoExport(stage, bindableRoots, mergeTransformAndShape, overrideRootPath); } } else {