Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MAYA-102319 Basic useRegistry import support #621

Merged
merged 11 commits into from
Jul 20, 2020
4 changes: 4 additions & 0 deletions lib/mayaUsd/fileio/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ target_sources(${PROJECT_NAME}
primWriterContext.cpp
primWriterRegistry.cpp
registryHelper.cpp
shaderReader.cpp
shaderReaderRegistry.cpp
shaderWriter.cpp
transformWriter.cpp
writeJobContext.cpp
Expand All @@ -43,6 +45,8 @@ set(headers
primWriterContext.h
primWriterRegistry.h
registryHelper.h
shaderReader.h
shaderReaderRegistry.h
shaderWriter.h
transformWriter.h
writeJobContext.h
Expand Down
2 changes: 1 addition & 1 deletion lib/mayaUsd/fileio/primWriterContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

PXR_NAMESPACE_OPEN_SCOPE

/// \class UsdMayaPrimReaderContext
/// \class UsdMayaPrimWriterContext
/// \brief This class provides an interface for writer plugins to communicate
/// state back to the core usd maya logic.
class UsdMayaPrimWriterContext
Expand Down
45 changes: 45 additions & 0 deletions lib/mayaUsd/fileio/shaderReader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// Copyright 2018 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "shaderReader.h"

#include <maya/MFnDependencyNode.h>
#include <maya/MString.h>

#include <pxr/base/tf/token.h>
#include <pxr/pxr.h>
#include <pxr/usd/sdf/path.h>
#include <pxr/usd/usd/attribute.h>
#include <pxr/usd/usd/prim.h>

#include <mayaUsd/fileio/primReaderArgs.h>
#include <mayaUsd/fileio/primReaderContext.h>

PXR_NAMESPACE_OPEN_SCOPE

UsdMayaShaderReader::UsdMayaShaderReader(const UsdMayaPrimReaderArgs& readArgs)
: UsdMayaPrimReader(readArgs)
{
}

/* virtual */
TfToken
UsdMayaShaderReader::GetMayaNameForUsdAttrName(
const TfToken& usdAttrName)
{
return TfToken();
}

PXR_NAMESPACE_CLOSE_SCOPE
67 changes: 67 additions & 0 deletions lib/mayaUsd/fileio/shaderReader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//
// Copyright 2018 Pixar
// Copyright 2020 Autodesk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef PXRUSDMAYA_SHADER_READER_H
#define PXRUSDMAYA_SHADER_READER_H

#include <mayaUsd/base/api.h>
#include <mayaUsd/fileio/primReader.h>

#include <pxr/pxr.h>

#include <maya/MObject.h>
#include <maya/MPlug.h>

#include <memory>

PXR_NAMESPACE_OPEN_SCOPE

class TfToken;
class UsdMayaPrimReaderArgs;

/// Base class for USD prim readers that export Maya shading nodes as USD
/// shader prims.
class UsdMayaShaderReader : public UsdMayaPrimReader {
public:
MAYAUSD_CORE_PUBLIC
UsdMayaShaderReader(const UsdMayaPrimReaderArgs&);

/// Get the name of the Maya shading attribute that corresponds to the
/// USD attribute named \p usdAttrName.
///
/// The default implementation always returns an empty string, which
/// effectively prevents any connections from being authored to or from
/// the imported shader nodes. Derived classes should override this and
/// return the corresponding attribute names for the USD attributes
/// that should be considered for connections.
MAYAUSD_CORE_PUBLIC
virtual TfToken GetMayaNameForUsdAttrName(const TfToken& usdAttrName);

/// Get the Maya object created by this shader reader
///
MAYAUSD_CORE_PUBLIC
MObject GetMayaObject() { return _mayaObject; }

protected:

MObject _mayaObject;
};

typedef std::shared_ptr<UsdMayaShaderReader> UsdMayaShaderReaderSharedPtr;

PXR_NAMESPACE_CLOSE_SCOPE

#endif
93 changes: 93 additions & 0 deletions lib/mayaUsd/fileio/shaderReaderRegistry.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
//
// Copyright 2016 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "shaderReaderRegistry.h"

#include <mayaUsd/base/debugCodes.h>
#include <mayaUsd/fileio/functorPrimReader.h>
#include <mayaUsd/fileio/registryHelper.h>

#include <pxr/base/plug/registry.h>
#include <pxr/base/tf/debug.h>
#include <pxr/base/tf/diagnostic.h>
#include <pxr/base/tf/registryManager.h>
#include <pxr/base/tf/staticTokens.h>
#include <pxr/base/tf/stl.h>
#include <pxr/base/tf/token.h>
#include <pxr/pxr.h>

#include <map>
#include <string>
#include <utility>

PXR_NAMESPACE_OPEN_SCOPE

TF_DEFINE_PRIVATE_TOKENS(_tokens, (UsdMaya)(ShaderReader));

typedef std::map<std::string, UsdMayaShaderReaderRegistry::ReaderFactoryFn> _Registry;
static _Registry _reg;

/* static */
void UsdMayaShaderReaderRegistry::Register(
const std::string& usdInfoId,
UsdMayaShaderReaderRegistry::ReaderFactoryFn fn)
{
TF_DEBUG(PXRUSDMAYA_REGISTRY)
.Msg("Registering UsdMayaShaderReader for info:id %s.\n", usdInfoId.c_str());

std::pair<_Registry::iterator, bool> insertStatus = _reg.insert(std::make_pair(usdInfoId, fn));
if (insertStatus.second) {
UsdMaya_RegistryHelper::AddUnloader([usdInfoId]() { _reg.erase(usdInfoId); });
} else {
TF_CODING_ERROR("Multiple readers for id %s", usdInfoId.c_str());
}
}

/* static */
void UsdMayaShaderReaderRegistry::RegisterRaw(
const std::string& usdInfoId,
UsdMayaShaderReaderRegistry::ReaderFn fn)
{
Register(usdInfoId, UsdMaya_FunctorPrimReader::CreateFactory(fn));
}

/* static */
UsdMayaShaderReaderRegistry::ReaderFactoryFn
UsdMayaShaderReaderRegistry::Find(const std::string& usdInfoId)
{
TfRegistryManager::GetInstance().SubscribeTo<UsdMayaShaderReaderRegistry>();

ReaderFactoryFn ret = nullptr;
if (TfMapLookup(_reg, usdInfoId, &ret)) {
return ret;
}

static const TfTokenVector SCOPE = { _tokens->UsdMaya, _tokens->ShaderReader };
UsdMaya_RegistryHelper::FindAndLoadMayaPlug(SCOPE, usdInfoId);

// ideally something just registered itself. if not, we at least put it in
// the registry in case we encounter it again.
if (!TfMapLookup(_reg, usdInfoId, &ret)) {
TF_DEBUG(PXRUSDMAYA_REGISTRY)
.Msg(
"No usdMaya reader plugin for info:id %s. No maya plugin found.\n",
usdInfoId.c_str());
_reg[usdInfoId] = nullptr;
}

return ret;
}

PXR_NAMESPACE_CLOSE_SCOPE
137 changes: 137 additions & 0 deletions lib/mayaUsd/fileio/shaderReaderRegistry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
//
// Copyright 2016 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef PXRUSDMAYA_SHADER_READER_REGISTRY_H
#define PXRUSDMAYA_SHADER_READER_REGISTRY_H

#include <mayaUsd/base/api.h>
#include <mayaUsd/fileio/primReaderArgs.h>
#include <mayaUsd/fileio/primReaderContext.h>
#include <mayaUsd/fileio/shaderReader.h>

#include <pxr/pxr.h>
#include <pxr/usd/sdf/path.h>

#include <maya/MFnDependencyNode.h>

#include <functional>
#include <string>

PXR_NAMESPACE_OPEN_SCOPE

/// \class UsdMayaShaderReaderRegistry
/// \brief Provides functionality to register and lookup USD shader reader
/// plugins for Maya nodes.
///
/// Use PXRUSDMAYA_DEFINE_SHADER_READER(usdInfoId, args, ctx) to define a new
/// reader function, or use
/// PXRUSDMAYA_REGISTER_SHADER_READER(usdInfoId, readerClass) to register a
/// reader class with the registry.
///
/// In order for the core system to discover the plugin, you need a
/// \c plugInfo.json that contains the usdInfoId and the Maya plugin to load:
/// \code
/// {
/// "UsdMaya": {
/// "ShaderReader": {
/// "mayaPlugin": "myMayaPlugin",
/// "providesTranslator": [
/// "myCustomShaderId"
/// ]
/// }
/// }
/// }
/// \endcode
///
/// The registry contains information for both Maya built-in node types
/// and for any user-defined plugin types. If UsdMaya does not ship with a
/// reader plugin for some Maya built-in type, you can register your own
/// plugin for that Maya built-in type.
struct UsdMayaShaderReaderRegistry {
/// Reader factory function, i.e. a function that creates a prim reader
/// for the given prim reader args.
typedef std::function<UsdMayaPrimReaderSharedPtr(const UsdMayaPrimReaderArgs&)> ReaderFactoryFn;

/// Reader function, i.e. a function that reads a prim. This is the
/// signature of the function declared in the PXRUSDMAYA_DEFINE_READER
/// macro.
typedef std::function<bool(const UsdMayaPrimReaderArgs&, UsdMayaPrimReaderContext*)> ReaderFn;

/// \brief Register \p fn as a factory function providing a
/// UsdMayaShaderReader subclass that can be used to read \p usdInfoId.
/// If you can't provide a valid UsdMayaShaderReader for the given arguments,
/// return a null pointer from the factory function \p fn.
///
/// Example for registering a reader factory in your custom plugin:
/// \code{.cpp}
/// class MyReader : public UsdMayaShaderReader {
/// static UsdMayaPrimReaderSharedPtr Create(
/// const UsdMayaPrimReaderArgs&);
/// };
/// TF_REGISTRY_FUNCTION_WITH_TAG(UsdMayaShaderReaderRegistry, MyReader) {
/// UsdMayaShaderReaderRegistry::Register("myCustomInfoId",
/// MyReader::Create);
/// }
/// \endcode
MAYAUSD_CORE_PUBLIC
static void Register(const std::string& usdInfoId, ReaderFactoryFn fn);

/// \brief Wraps \p fn in a ReaderFactoryFn and registers the wrapped
/// function as a prim reader provider.
/// This is a helper method for the macro PXRUSDMAYA_DEFINE_SHADER_READER;
/// you probably want to use PXRUSDMAYA_DEFINE_SHADER_READER directly
/// instead.
MAYAUSD_CORE_PUBLIC
static void RegisterRaw(const std::string& usdInfoId, ReaderFn fn);

/// \brief Finds a reader if one exists for \p usdInfoId.
///
/// If there is no reader plugin for \p usdInfoId, returns nullptr.
MAYAUSD_CORE_PUBLIC
static ReaderFactoryFn Find(const std::string& usdInfoId);
};

// Note, TF_REGISTRY_FUNCTION_WITH_TAG needs a type to register with so we
// create a dummy struct in the macro.

/// \brief Registers a pre-existing reader class for the given USD info:id;
/// the reader class should be a subclass of UsdMayaShaderReader with a
/// constructor that takes <tt>(const UsdMayaPrimReaderArgs& readerArgs)</tt>
/// as argument.
///
/// Example:
/// \code{.cpp}
/// class MyReader : public UsdMayaPrimReader {
/// MyReader(
/// const MFnDependencyNode& depNodeFn,
/// const SdfPath& usdPath,
/// UsdMayaReadeJobContext& jobCtx) {
/// // ...
/// }
/// };
/// PXRUSDMAYA_REGISTER_WRITER(myCustomMayaNode, MyReader);
/// \endcode
#define PXRUSDMAYA_REGISTER_SHADER_READER(usdInfoId, readerClass) \
TF_REGISTRY_FUNCTION_WITH_TAG(UsdMayaShaderReaderRegistry, usdInfoId##_##readerClass) \
{ \
UsdMayaShaderReaderRegistry::Register( \
#usdInfoId, [](const UsdMayaPrimReaderArgs& readerArgs) { \
return std::make_shared<readerClass>(readerArgs); \
}); \
}

PXR_NAMESPACE_CLOSE_SCOPE

#endif
5 changes: 5 additions & 0 deletions lib/mayaUsd/fileio/shading/shadingModeImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,5 +178,10 @@ UsdMayaShadingModeImportContext::SetDisplacementShaderPlugName(
_displacementShaderPlugName = displacementShaderPlugName;
}

UsdMayaPrimReaderContext*
UsdMayaShadingModeImportContext::GetPrimReaderContext() const
{
return _context;
}

PXR_NAMESPACE_CLOSE_SCOPE
5 changes: 5 additions & 0 deletions lib/mayaUsd/fileio/shading/shadingModeImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ class UsdMayaShadingModeImportContext
MAYAUSD_CORE_PUBLIC
void SetDisplacementShaderPlugName(const TfToken& displacementShaderPlugName);

/// Returns the primitive reader context for this shading mode import.
///
MAYAUSD_CORE_PUBLIC
UsdMayaPrimReaderContext* GetPrimReaderContext() const;

private:
const UsdShadeMaterial& _shadeMaterial;
const UsdGeomGprim& _boundPrim;
Expand Down
Loading