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-104984 MAYA-104641 - Material export via registry #574

Merged
merged 11 commits into from
Jun 17, 2020

Conversation

JGamache-autodesk
Copy link
Collaborator

@JGamache-autodesk JGamache-autodesk commented Jun 9, 2020

Changes:

  • Exposed the "useRegistry" shading export mode in the export dialog.
  • Wrote registry classes to export Maya lambert, phong, blinn, standard_surface materials to USDPreviewSurface.
  • Moved the listShadingModes command from pxr to usdMayaPlugin
  • Moved the pxrUsdPreviewSurface plugin to usdMayaPlugin.
    The shading node overrides uses the same VP2 fragments as the Vp2 render delegate.

@@ -3,6 +3,7 @@
# -----------------------------------------------------------------------------
target_sources(${PROJECT_NAME}
PRIVATE
listShadingModesCommand.cpp
shadingModeDisplayColor.cpp
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Moved from pxr plugin.

static
bool
_AuthorShaderInputFromShadingNodeAttr(
const MFnDependencyNode& depNodeFn,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Greatly inspired by the UsdPreviewSurface writer.

@@ -43,8 +44,6 @@ def setUp(self):
def _WriteViewportImage(self, outputImageName, suffix):
# Make sure the hardware renderer is available
MAYA_RENDERER_NAME = 'mayaHardware2'
mayaRenderers = cmds.renderer(query=True, namesOfAvailableRenderers=True)
self.assertIn(MAYA_RENDERER_NAME, mayaRenderers)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This command only seem to work in interactive. We can still continue to the ogsRender command.

@kxl-adsk kxl-adsk added the import-export Related to Import and/or Export label Jun 10, 2020
Copy link

@kxl-adsk kxl-adsk left a comment

Choose a reason for hiding this comment

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

Looking good. I left a few comments, the biggest one being:

  • coupling of Pixar and adsk plugins which we want to avoid
  • the move of image comparison tests which we are not running

plugin/adsk/plugin/plugin.cpp Outdated Show resolved Hide resolved
$niceName = "Material Colors";
} else if ($modeName == "pxrRis") {
$niceName = "RfM Shaders";
} else if ($modeName == "useRegistry") {

Choose a reason for hiding this comment

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

One can implement an exporter using a shader registry which doesn't translate to preview surface. We have more work in here - do you agree?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, the exporter should register with a name that reflects the target, not the process. Follow-up exporters using the registry should do the same. They should probably be expected to provide their own nice name as well.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think I'm second'ing @kxl-adsk's point here. My intention with the addition of the useRegistry shading mode was that it would be the extensible registry for adding arbitrary exporters for whatever shading node types you wanted to write. With the addition of that, I would not expect that we would ever add any more shading modes, and in fact, over time I'd hope that we'd eventually remove the concept of shading modes.

It so happens that the only exporters currently supported by the useRegistry shading mode generate UsdPreviewSurface, but that would definitely not always be the case, so the nice name doesn't really seem appropriate to me.

plugin/pxr/maya/plugin/pxrUsd/plugin.cpp Show resolved Hide resolved
plugin/pxr/maya/plugin/pxrUsdPreviewSurface/plugin.cpp Outdated Show resolved Hide resolved
test/lib/usd/pxrUsdPreviewSurface/CMakeLists.txt Outdated Show resolved Hide resolved
@@ -29,8 +30,9 @@ def setUpClass(cls):
# that way too.
cmds.upAxis(axis='z')

cls._testDir = os.path.abspath('.')

cls._testDir = os.path.join(os.path.abspath('.'),

Choose a reason for hiding this comment

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

We are currently not running draw tests...I will let @mattyjams comment on the move of this file + all the supporting image files.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm going to have to do something about this internally anyway, since we don't run CMake/CTest at all and instead have a parallel setup through SCons. Luckily, pxrUsdPreviewSurface is not (yet) a critical piece of any real workflows, so it's not absolutely necessary that the test be addressed immediately, but it would obviously be better for it to get running again.

I would love to figure out how to get drawing/interactive tests running in this repo though, both for this test and for the others that are still in pxrUsdMayaGL.

Copy link
Contributor

@HamedSabri-adsk HamedSabri-adsk left a comment

Choose a reason for hiding this comment

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

Hi @JGamache-autodesk ,

mayaUsd_copyFiles is redundant and should be removed. mayaUsd_copyDirectory will copy everything from maya-usd/test/lib/usd/pxrUsdPreviewSurface which is your SOURCE to DESTINATION .

You would also want to exclude any *.txt files since they are not needed to be copied over to the build area.

# copy all the resources and python scripts to build directory
mayaUsd_copyDirectory(${TARGET_NAME}
    SOURCE ${CMAKE_CURRENT_SOURCE_DIR}
    DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
    EXCLUDE "*.txt"
)

Other than this, everything else looks good. Thanks.

Copy link
Contributor

@HamedSabri-adsk HamedSabri-adsk left a comment

Choose a reason for hiding this comment

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

Lgtm! thanks.

One very minor thing, I noticed the original pxr_register_test has MAYA_DISABLE_CIP=1, which is used to avoid fatal crash on start-up. I wonder if we still need this to be set?

I also think we should set MAYA_DISABLE_CER=1 in test.cmake for all the tests to avoid getting the Customer Error Reporting in case of test failures. Again, something for another PR.

@@ -32,23 +31,27 @@ class testPxrUsdPreviewSurfaceExport(unittest.TestCase):

@classmethod
def setUpClass(cls):
standalone.initialize('usd')
testDir = os.path.join(os.path.abspath('.'),

Choose a reason for hiding this comment

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

@ppt-adsk You are moving tests out of Pixar plugin for import/export - where should we be saving these temporary files? Should it go under temp folder (so follow AL example and usage of NamedTemporaryFile) or maybe you found a different solution?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I believe I'm doing something similar to this, creating an output directory for the test if it is not already created, and emptying it out if it is. This is in the build area.

Choose a reason for hiding this comment

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

Why not leverage NamedTemporaryFile? (https://docs.python.org/3/library/tempfile.html)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Why use that? If I want to look at files after a test run, I know exactly where to look in the build area. This is often very useful to diagnose test problems.

Copy link
Collaborator

Choose a reason for hiding this comment

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

The existing Pixar test run setup used temporary files, did not clean them up, and this left an increasing amount of useless files in the temporary area.

Choose a reason for hiding this comment

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

Knowing where to look for them in a very good argument. I like it, but let's be a bit more specific about:

  1. where in the build folder we should expect to find these temporary test files
  2. rules about leaving and clearing the temporary test files folder

Copy link
Collaborator

Choose a reason for hiding this comment

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

As my implementation currently stands, the output files are placed in a per-test subdirectory of the build importExport directory, where all the import / export tests live, and where the .pyc files are written. The subdirectory is called Output, one per test. The files are always left after the test run, and always cleaned at the start of the test run. If you feel this deserves further conversation, we can do so outside this review.

Choose a reason for hiding this comment

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

I would like us to align in how tests are dealing with it.

Copy link
Contributor

Choose a reason for hiding this comment

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

The subdirectory is called Output, one per test. The files are always left after the test run, and always cleaned at the start of the test run.

This is great. @kxl-adsk Pierre's points makes a lot of sense to me. We can talk about this internally later so we are all aligned.

Copy link

@kxl-adsk kxl-adsk left a comment

Choose a reason for hiding this comment

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

Thank you for addressing my comments @JGamache-autodesk. The last thing that remains is the move of .png files and draw test. I will let @mattyjams comment on it.

Copy link
Contributor

@mattyjams mattyjams left a comment

Choose a reason for hiding this comment

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

A handful of small notes and ideas, but two main points:

  • I think it's important that the useRegistry shading mode not be thought of as the mode to use to export everything as UsdPreviewSurface, even though that may be what it currently does today based on the exporters that we're registering. Eventually, hopefully other shading node types that might not generate UsdPreviewSurface in USD could be exported through the same mechanism. Ideally, we wouldn't see the "shading mode" concept extended any further to include any additional shading modes, and we would instead represent all shading import and export through useRegistry.

  • Somewhat to that end, it feels like all of the shading node type or UsdPreviewSurface specific stuff in materialWriter.cpp should be factored out into discrete files and classes, leaving the base material writer class as a type-agnostic framework that can be extended to support individual node types.

It's not critical that that be done before this gets merged, so I'll mark this as approved, but it would be great to address that soon after with a follow-up PR.

For the unit test, I think I'm ok with it moving and not yet being run through the usual CTest harness, as I'm going to have to do some work internally to get it running in our SCons-based system anyway.

lib/mayaUsd/commands/baseListShadingModesCommand.cpp Outdated Show resolved Hide resolved
lib/usd/pxrUsdPreviewSurface/CMakeLists.txt Outdated Show resolved Hide resolved
lib/usd/pxrUsdPreviewSurface/CMakeLists.txt Outdated Show resolved Hide resolved
lib/usd/pxrUsdPreviewSurface/CMakeLists.txt Outdated Show resolved Hide resolved
Comment on lines +49 to +67
PXRUSDMAYA_REGISTER_WRITER(
lambert,
PxrUsdTranslators_MaterialWriter);

PXRUSDMAYA_REGISTER_WRITER(
blinn,
PxrUsdTranslators_MaterialWriter);

PXRUSDMAYA_REGISTER_WRITER(
phong,
PxrUsdTranslators_MaterialWriter);

PXRUSDMAYA_REGISTER_WRITER(
phongE,
PxrUsdTranslators_MaterialWriter);

PXRUSDMAYA_REGISTER_WRITER(
standardSurface,
PxrUsdTranslators_MaterialWriter);
Copy link
Contributor

Choose a reason for hiding this comment

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

It feels to me like all of the shading node type-specific stuff should not live in this file, and should probably be distinct files and probably even classes per type. This file/class would then provide the basis for and common functionality between all shader writers, which they can extend to support whatever type-specific stuff they want to do.

There should be nothing in here that's specific to any particular type of Maya shading node, nor anything having to do with UsdPreviewSurface.

Comment on lines +209 to +223
MPlug scalingPlug =
depNodeFn.findPlug(
depNodeFn.attribute(scalingAttrName.GetText()),
/* wantNetworkedPlug = */ true,
&status);
if (status == MS::kSuccess) {
VtValue vtScale =
UsdMayaWriteUtil::GetVtValue(
scalingPlug,
SdfValueTypeNames->Float);

if (vtScale.IsHolding<float>()) {
colorScale = vtScale.UncheckedGet<float>();
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This scaling stuff again seems specific to a particular subset of shading node types.

return;
}

if (GetMayaObject().hasFn(MFn::Type::kBlinn)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

The battery of MFn::Type-based checks below seem useful maybe as individual helper functions that discrete node-specific exporters could compose as appropriate, rather than having every node pass through every possible MFn::Type.

# Conflicts:
#	plugin/pxr/maya/plugin/pxrUsdPreviewSurface/pxrUsdPreviewSurfaceGenFragments.py
"Type": "resource"
"LibraryPath": "../../../@CMAKE_SHARED_LIBRARY_PREFIX@@TARGET_NAME@@CMAKE_SHARED_LIBRARY_SUFFIX@",
"Name": "@TARGET_NAME@",
"Type": "library"
}
Copy link
Collaborator Author

@JGamache-autodesk JGamache-autodesk Jun 15, 2020

Choose a reason for hiding this comment

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

Based on plugInfo.json in lib/usd/translators.
How do we handle the fact that 2 Maya plugins will provide the same translator? Should I use mayaUsdPlugin instead at line 7?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the change in structure actually means that you could leave the mayaPlugin field above empty. The node and the translator are now getting bundled into the mayaUsd library itself, right?

if (!mayaPlugin.empty()) {

The mayaUsd library itself is what provides the translator, so it's not actually necessary to load any plugins to ensure that the translator has been registered, since the library will already have been loaded.

As it is now, I think if you only had the adsk mayaUsdPlugin loaded and you did an export, it would needlessly load the pxr pxrUsdPreviewSurface plugin thinking it needs to do so in order to make sure the translator is available.

Choose a reason for hiding this comment

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

@mattyjams We want to keep the original plugin structure for preview surface, i.e. the node and the translator is not part of mayaUsd library. This is why we put it in lib/usd and not lib/mayaUsd.

What Jerry talks about is the current limitation where you can have only one translator registered per node type. We will need to support more than one.

As for line 7 - pxrUsdPreviewSurface is a plugin that shouldn't be dependent on ADSK, AL, nor PXR plugins. Why would we need to put mayaUsdPlugin in there?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Indeed the plugInfo.json file is not necessary. The writer will get registered as soon as the basePxrUsdPreviewSurface DLL gets loaded in memory, which will happen as soon as one of the two plugins using UsdPreviewSurface gets loaded.

Copy link
Contributor

@mattyjams mattyjams Jun 16, 2020

Choose a reason for hiding this comment

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

The plugInfo.json is probably not strictly necessary for export, no, since as you mentioned, the library that provides the translator will already have been loaded to make the node itself available.

It would definitely be necessary for import though, albeit that's not implemented yet. You'll need to loadPlugin something in order to have that library be loaded in the case where you're importing into an empty scene and the importer encounters a shader of that type. And if we're going to (eventually) include an entry in the plugInfo.json for import, it would be nice to have an entry for export as well, just for completeness.

pxrUsdPreviewSurface will live in lib/usd with this change, but what could cause that library to be loaded other than doing a loadPlugin of either mayaUsdPlugin or pxrUsdPreviewSurface (the Maya plugin from pxr)?

@kxl-adsk kxl-adsk merged commit f45f050 into dev Jun 17, 2020
@kxl-adsk kxl-adsk deleted the t_gamaj/MAYA-104984/use_registry_export branch June 17, 2020 15:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
import-export Related to Import and/or Export
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants