The Maya Viewport 2.0 whitepaper can be found at http://www.autodesk.com/developmaya.
This document is divided into two parts. The first (Viewport 2.0 API Porting Guide) is an overview of Viewport 2.0 and outlines the differences between the legacy default viewport and Viewport 2.0. The second part (Viewport 2.0 API Porting Guide Details) is more detailed and specifies the recommended interfaces and provides code examples for common tasks.
The Improving Performance with Parallel Evaluation whitepaper can be found at http://www.autodesk.com/maya-docs.
Refer to this document for information on how to use the new Evaluation Manager feature to improve playback and manipulation of your animated scenes through scene-level graph analysis and parallelization. In addition, it provides information on the API extensions that your plug-in can implement to take advantage of these features, as well as guidelines on how to use the Profiler to evaluate performance in your scene.
Maya 2016 Extension 2 is not binary compatible with Maya 2016.
C++ plug-ins that were compiled against Maya 2016 or Maya 2016 Extension 1, including Maya 2016 service pack releases, must be re-compiled against Maya 2016 Extension 2 in order to be recognized by this version of Maya.
In addition, plug-ins compiled against Maya 2016 Extension 2 will either not load or exhibit unpredictable behavior if loaded in Maya 2016, Maya 2016 Extension 1, or any Maya 2016 service pack release.
To obtain the Maya 2016 and Maya 2016 Extension 1 API Guide, see http://www.autodesk.com/me-sdk-docs-2016.
The C++ API header files and libraries are now available with the Maya installation. It is no longer necessary to download the Maya Developer Kit in order to compile your custom plug-ins. The header and library files can be found in the following folders of your Maya installation:
Windows and Linux:
Mac OS X:
The Developer Kit is available online at Autodesk Exchange at https://apps.exchange.autodesk.com/MAYA/en/Home/Index.
You can now register a Maya Node ID block or a Tangent Types ID block at http://mayaid.autodesk.io/. See also the Tools & Documentation archives section at http://www.autodesk.com/developmaya for more information.
Jump to the following sections:
The following classes and methods have been added to Python API 2.0:
A Python API 2.0 version of the example has been added to Example: Creating a Scene, and the Python API 2.0 example on Querying the Scene Graph updated as a result.
Added pyApiMeshShape developer kit example to illustrate component selection.
Python examples are available in the plug-ins\scripted directory of the Maya Developer Kit.
The following classes can now be initialized with sequences of compatible elements:
For example, you can now create an MPointArray with a sequence of sequences (including lists and tuples), without the need to first create an MPoint for each sequence.
In other words, you can now do the following:
pySeq = [[1,2,3],[4,5,6]] a = OpenMaya.MPointArray(pySeq)
instead of having to do the following:
a = OpenMaya.MPointArray([OpenMaya.MPoint(i) for i in pySeq])
You can also do the following:
adaptList = [ (-3.787, 0.05, 2), [189.3, 4.0, 4.01], om.MFloatPoint(0.0002, 16.35, -8.9), om.MVector(1, 2, 3), om.MPoint(-6.314, 2.09, 17.8) ] fpa = om.MFloatPointArray(adaptList) pa = om.MPointArray(fpa) ta = om.MTimeArray([0,4,8,15,17])
See Semantics and annotations supported by the dx11Shader and glslShader plug-ins in Viewport 2.0 and Shader semantics supported by Viewport 2.0.
See the pointManip developer kit example. When dragging the pointManip, the selected objects are moved to the closest intersection point between the mouse ray and opaque objects, which is calculated from the screen-space position and the corresponding depth value.
MDrawContext
See the rawfootPrintNode andglslShader plug-in examples for usage of getFrameStamp().
Added new method MFrameContext::getEnvironmentParameters().
This method returns the environment parameters set for the current viewport. Can be used in the draw phase for a plug-in hardware shader to check if an environment map is set for the current viewport (the method is accessed on the MDrawContext given to the shader). If an environment is enabled, the path to the environment image file is given. The image is always in latlong format. Note that this information is set per viewport and therefore may change between successive draw calls if multiple viewports are displayed at the same time.
Currently, environments are only used by the Material Viewer in the Hypershade. For all other viewports, the environment is always set to disabled.
Added object type exclusion statics to MFrameContext.
Note that a MUint64 value is returned to allow for a complete set of exclusions to be accessed.
MUint64 objectTypeExclusions() const;
Exclusion by classification string has been newly added:
void classificationExclusions(MStringArray &classification) const;
The statics on MFrameContext should be instead of the enum MSceneRender::MObjectTypeExclusions, which has a subset of the new enum list.
MSceneRender::getObjectTypeExclusions() has been added to return a MUint64 type. The objectTypeExclusions() method that returns MObjectTypeExclusions is considered to be obsolete, but will still work unless MSceneRender::getObjectTypeExclusions() is overridden.
The viewImageBlitOverride and pyViewRenderOverride.py plug-in examples have been updated to use the new MFrameContext statics.
A number of additions have been made to MFrameContext to enable querying of state information without having to access M3dView. These include:
The example plug-in rawfootPrintNode in the Maya Developer Kit has been modified to include debugging code to perform these queries.
Added MFrameContext::worldToViewport() and MFrameContext::viewportToWorld() methods that convert co-ordinates.
This method converts the co-ordinates in world space to co-ordinates in the viewport:
void worldToViewport(const MPoint &inPoint, double &xPos, double &yPos) const;
This method converts co-ordinates in the viewport to the near clipping plane co-ordinates in world space:
The example plug-in uiDrawManager demonstrates the use of these methods when drawing 2d text and 3d text.
MPassContext
MPassContext::shaderOverrideInstance() has been added that returns the shader instance for the current shader override. It allows you to use the shader program and parameters that Maya normally uses when drawing.
See the rawFootPrintnode example plug-in in the Developer Kit for more information.
MPxPrimitiveGenerator and MRenderItem
These primitive types can now be used everywhere that a primitive is set in Viewport 2.0, including a new triangle adjacency MPxPrimitiveGenerator in the GLSL shader plug-in (see adjacentTrianglesPrimitiveGenerator.cpp in the glslShader plug-in folder in the Developer Kit). Refer to SilhouetteEdge.ogsfx for an example of how this new generator enables the drawing of silhouette edges (see the presets\GLSL\examples folder of the Maya installation directory).
MPxDrawOverride
MPxDrawOverride::isTransparent() has been added to indicate that the object needs to be drawn as transparent.
If /isTransparent is added to the geometry classification drawdb/geometry/myNode/isTransparent/, then the plug-in will be called during transparent passes.
You must consider post effects also. The classification drawdb/geometry/includePostEffects/ ensures that post effects are called for your draw override. To ensure that both isTransparent and includePostEffects take effect, set the classification as drawdb/geometry/rawfootPrint/isTransparent/includePostEffects.
See the rawfootPrintNode plug-in example.
MPxDrawOverride can opt-in to being called from post-effects passes by specifying a classification of drawdb/geometry/includePostEffects. By default, draw overrides are not called for additional post-effect passes such as: depth-of-field, screen space ambient occlusion, and motion-blur.
MPxDrawOverride::excludedFromPostEffects() can be used to exclude a draw override from being called for post-effects passes. See the rawfootPrintNode plug-in example.
New pass semantics have been added to MPassContext - MPassContext::kDOFPassSemantic, and MPassContext::kMotionVectorPassSemantic. These are equivalent to checking for the strings dofPass and motionVectorPass in previous releases. MPassContext::kPEPatternPassSemantic and MPassContext::kNonPEPatternPassSemantic have been added to indicate a post effect pattern pass and a non post effect pattern pass, respectively.
The ProjectionZSense semantic has been added that denotes whether the projection matrix flips the Z component of a point when transformed: if so, its value is -1.0; otherwise 1.0. See Shader semantics supported by Viewport 2.0.
For more information regarding these passes, see Effects interfaces.
The MShaderInstance::requiredVertexBuffers() method allows you to query a list of vertex buffer descriptors for a given shader instance (MVertexBufferDescriptorList).
Subscene overrides, in particular, can make use of this method when using shader instances for custom render items, although this method can be called outside of the context of this override.
This method is used in the GLSL shader plug-in. Refer to glslShader in the developer kit. See configureGeometryRequirements() on the GLSLShaderNode class where the results are examined to configure MVaryingParameters.
The MShaderManager::getShaderFromNode() and MRenderItem::setShaderFromNode() interfaces have a new boolean argument nonTextured added that allows users to use a non-textured effect instance.
See MPxPrimitiveGenerator and MRenderItem in the Drawing section above.
The MShaderInstance::techniqueNames() method has been added that returns the list of techniques from a shader instance. This method is also available in Python API 2.0.
A similar method MShaderManager::getEffectsTechniques() currently exists that loads an effects file and extracts the names of the defined techniques. However, this function can only be used when loading effects from files and cannot be used when loading effects from string buffers. You can now use the new MShaderInstance::techniqueNames() once the effect is loaded.
When acquiring a shader via any one of the various interfaces on MShaderManager, such as MShaderManager::getEffectsFileShader() or MShaderManager::getEffectsBufferShader(), if a shader compilation failure occurs, then errors will be output to the Output Window on Windows and Linux, and to the console on Mac. This aids in the debugging process for shader writers.
When a shader cannot be returned, a NULL value will be returned.
In particular, this is now true if the string buffer method MShaderManager::getEffectsBufferShader() is used. Previously, an error shader was returned, making it difficult to recognize if a failure had occurred.
The MRenderItem::setShaderFromNode() and MShaderManager::getShaderFromNode() interfaces have a new boolean argument nonTextured added that allows users to use a non-textured effect instance.
MRenderItem::setShaderFromNode() is the recommended interface because it does not expose internal effect instances. Its use is demonstrated in the apiMeshShape plug-in example (apiMeshSubSceneOverride.cpp) in the Developer Kit.
Previously, this sample plug-in created only one render item for both its shaded mode and textured mode. In the new version, two render items are created: one for shaded mode, the other for the textured mode. Their effect instances are both assigned with MRenderItem::setShaderFromNode(), but the boolean argument nonTextured is set true for the shaded render item and false for the textured one.
MPxShaderOverride
bool MPxShaderOverride::requiresUnsharedGeometricStreams()
A plug-in can override this method to return true in order to force geometric streams to be expanded.
See also the animCubeNode example, which, when the MAYA_TEST_VERTEXID_AND_FACEID environment variable is set, produces a cube the topology of which changes every 4 frames. When the hwPhongShader is assigned to this shape, the shader receives vertex ids and face ids that are generated from the animCubeNode plug-in.
MPxHwShaderNode
The Legacy Default Viewport, by default, returns unshared data.
Previously, vertex ids could be queried using the MPxHwShaderNode::provideVertexIDs() method. Face ids can now be queried using the new MPxHwShaderNode::provideFaceIDs() method. Local UV coordinates can now be queried using the new MPxHwShaderNode::provideLocalUVCoord() method.
There are new methods that return the data with this signature:
MStatus MPxHwShaderNode::geometry( const MDrawRequest& request, M3dView& view, int prim, unsigned int writable, int indexCount, const unsigned int * indexArray, int vertexCount, const int * vertexIDs, const float * vertexArray, int normalCount, const float ** normalArrays, int colorCount, const float ** colorArrays, int texCoordCount, const float ** texCoordArrays, const int *faceIDs, const float * localUVCoord)
Mstatus MPxHwShaderNode::glGeometry( const MDagPath& shapePath, int prim, unsigned int writable, int indexCount, const unsigned int * indexArray, int vertexCount, const int * vertexIDs, const float* vertexArray, int normalCount, floatArrayPtr normalArrays, int colorCount, floatArrayPtr colorArrays, int texCoordCount, floatArrayPtr texCoordArrays, const int * faceIDs, const float * localUVCoord)
The blindDataShader and hwPhongShader plug-in examples both demonstrate the use of this interface to retrieve vertex and face ids.
The blindDataShader example displays a grey-scale value for the corresponding face ids returned.
Note that the UV co-ordinates, face and vertex ids returned will be equivalent for both the Viewport 1 and Viewport 2.0 MPxShaderOverride interface (provided that the Viewport 2.0 interface asks for unshared data).
When a mesh is using smooth mesh preview, then the face ids returned are those of the original unsmoothed mesh while the vertex ids are those of the smoothed mesh.
MRenderItem
MRenderItem::sourceDagPath() always returns a dag path even when the item contains consolidated geometry (MRenderItem::isConsolidated()). When consolidated, it will return one dag path out of all dag paths contributing to the geometry. See Documentation updates for more information regarding the extraction of dag paths and geometry from consolidated geometry during draw time.
The use of MRenderItem::sourceIndexMapping() is preferable since this interface returns an appropriate list of dag paths.
The MTextureManager::acquireTexture() method:
MTexture* MTextureManager::acquireTexture(const MString& textureName, const MPlug& plug, int width, int height, bool generateMipMaps = true);
has been modified so that if a plug to a file texture node is specified, then an attempt will be made to read the file texture from disk. Previously, this method would bake the texture using the Maya Software renderer's convert to solid texture functionality. This modification allows for better fidelity and accuracy of the returned texture.
A new MTextureManager::acquireTexture() method:
MTexture* MTextureManager::acquireTexture(const MObject& textureNode, bool allowBackgroundLoad = false);
loads the file texture from a given texture node, and is the preferred method for file textures (over the previously mentioned plug method), as it provides a simpler interface. It takes a file texture node as an argument, and removes the requirement to specify parameters that are not needed (width, height, name, and generate mipmaps).
In addition, it exposes the option to indicate whether the Viewport 2.0 texture background loading feature should be used. See Material Loading Mode in the Display preferences section of the Maya User Guide for more information regarding texture background loading.
The new MTexture::update() method:
allows for update versus acquisition using a file texture node.
Currently, all file texture based methods have the limitation that they return the first tile if the file texture uses UV tiling.
In Maya 2016 Extension 2, Viewport 2.0 only evaluates lights up to the light limit. Therefore, if you want to request light information on demand, you must call the new MRenderer::needEvaluateAllLights() method.
If your plug-in calls the following interfaces:
MDrawContext::getLightInformation(kFilterIgnoreLightLimit)
You must first call this method before drawing.
If you do not want to modify your existing plug-in, you can also set an optionVar MAYA_VP2_IGNORE_EVALUATION_LIGHT_LIMIT=1 to ensure that your plug-in continues to work as it did before Extension 2. When this optionVar is set, all lights in your scene are evaluated at all times, regardless of whether you have loaded a plug-in. As a result, this optionVar may decrease the performance of Viewport 2.0 if you have a scene with many lights.
To mitigate this, you can set this optionVar to 0 again when your plug-in no longer needs to evaluate all lights, and Viewport 2.0 will revert back to only evaluating lights up to the light limit.
MGeometryExtractor now supports the following:
The geometryReplicator example plug-in demonstrates the support of these new features.
The MPxSubSceneOverride::setGeometryForRenderItem() interface has been updated so that when geometry is defined for drawing using a vertex buffer, for example by using MGeometry::kPoints, then it is no longer mandatory to also provide an MIndexBuffer. In this case, you can simply provide an empty MIndexBuffer to avoid wasting GPU memory. See the gpuCache Developer Kit plug-in for an example implementation.
Normalized clip planes may be computed for camera sets. This is the value returned by the existing MFnCamera::nearClippingPlane() and MFnCamera::farClippingPlane() methods. These new methods allow access to the original camera's clipping planes.
New methods to get the clip planes and unnormalized clip planes are now available as part of the draw context for Viewport 2.0.
The following enums have been added to MFrameContext:
MFrameContext::kViewNearClipValue //!< Camera near clip value (single value)
MFrameContext::kViewFarClipValue //!< Camera far clip value (single value)
MFrameContext::kViewUnnormlizedNearClipValue //!< Unnormalized camera near clip value (single value)
MFrameContext::kViewUnnormalizedFarClipValue //!< Unnormalized camera far clip value (single value)
which can be used from the MDrawContext::getTuple() method.
These produce the same results as when using MFnCamera::nearClippingPlane(), MFnCamera::farClippingPlane(), MFnCamera::unnormalizedNearClippingPlane(), and MFnCamera::unnormalizedFarClippingPlane() respectively.
See the rawfootPrintNode example plug-in for more information. See also Camera information.
See the viewRenderOverride and viewRenderOverridePostColor developer kit examples.
See the viewRenderOverrideMRT plug-in for sample code that draws to custom output targets that are larger than the active output target size.
It is now easier to implement an MRenderOverride. New classes and interfaces have been added that allow you to create a render override by populating a list of MRenderOperations. To create this list, you can obtain the list of standard viewport operations, and then optionally add to it your own custom operations.
This new method of implementation also eliminates the need for an MRenderOverride to manage and create render targets, as these are now managed by MRenderOperation.
New classes and interfaces added include:
Added a new method MPxContext::doPtrMoved(). This method is called when the mouse moves, so that mouse movements can be used to drive a subsequent action.
In the case of drawing, plug-ins should override this method when MUIDrawManager is used to perform drawing in Viewport 2.0.
Debug tracing information has been added for several override classes to help track evaluation order, as well as to the internal pipeline to track renderable list execution.
MPxDrawOverride and MPxGeometryOverride have new tracing methods (such as MPxDrawOverride::traceCallSequence() and MPxDrawOverride::handleTraceMessage(), and the ogs command has a new trace option (-traceRenderPipeline flag).
See Basic Viewport 2.0 Pipeline Sequencing and Basic Viewport 2 Object Sequencing for more information.
The Profiler now graphs rendering events that execute within Viewport 2.0. These events include node evaluation and UI drawables list/render list building, as well as draw events such as UV Editor drawing, beauty pass render, and UI drawables rendering (such as manipulator drawing). If you are using a render override plug-in, operations such as the quad render, 3d scene render and HUD render are also presented.
This feature allows you to identify render events or passes that may be performance bottlenecks in your scene
To filter these events, search for the prefix Vp2.
For more information on rendering events in Viewport 2.0, as well as information on what each event represents, see Profile Viewport 2.0 rendering events and Viewport 2.0 rendering events Profiler examples.
A new MRenderSetup class has been added that allows for access to Maya's new render setup functionality.
A new isAlwaysDirty parameter has been added to the MPxDrawOverride constructor. To optimize performance, set this attribute to false so that the draw override is only updated when the node is marked dirty via DG evaluation or dirty propagation. To explicitly mark an object as being dirty, call MRenderer::setGeometryDrawDirty().
See the transformDrawNode developer kit example for more information.
Performance is improved in scenes with many instances of nodes and that draw using MPxDrawOverride.
Performance improvement for viewport override plug-ins using the MRenderOverride interface.
The example plug-in fragmentDumper has also been updated to include the ability to dump the XML for a fragment with the specified name, as well as the ability to provide a list of all fragment names.
The viewObjectSetOverride plug-in has been modified to illustrate how to handle isolate selection in MSceneRender::objectSetOverride().
An object selected for isolate selection will only be shown if it also belongs to the specified object set; that is, set1 and set2.
Information regarding camera orientation in relation to the DirectX and OpenGL draw API's has been added to Camera information.
Information regarding shader consolidation has been added to Effect overrides: Consolidation considerations and Shader instances: Consolidation considerations.
Information about post effects passes added to Effects interfaces.
Added the following functions for tracking the GPU memory usage:
New convenience class that makes allocating, updating, and releasing OpenCL buffers easy
Added the following functions to get correct behavior in certain scenarios without having to turn off and turn on the GPU override:
Function to detect change in attributes
Added the following functions in the MOpenCLInfo class to localize strings.
MOpenCLInfo interface name change
MultiDraw consolidation support
MultiDraw consolidation is supported for MPxShaderOverride. An MPxShaderOverride plug-in based on MShaderInstances can now benefit from acceleration provided by MultiDraw consolidation if it can provide a MultiDraw-compatible MShaderInstance.
The following interfaces have been added for this feature:
MPxShaderOverride::shaderInstance(MHWRender::MDrawContext& context)
And this interface has been deprecated:
New shader semantics have also been added that are MultiDraw versions of world transformation, world-view transformation, and world-view-projection transformation matrices. See Shader semantics supported by Viewport 2.0.
See also the customTextureShader sample plug-in in the Developer Kit.
Updated the MFnBlendShapeDeformer interface
MFnBlendShapeDeformer::addTarget (const MObject& baseObject, int weightIndex, double fullWeight, TargetType targetType = kObject)
For example: calling createPixmap("test.png", true) may return test_150.png if the scale factor is 150%.
A new MFileIO::setError() method has been added that, when set, allows you to display the standard Maya file I/O pop-up window if an error occurs after a read or write operation. This method can only be invoked during a file I/O operation.
It is also recommended that you call MGlobal::displayError() when invoking MFileIO::setError() since the pop up window only contains a static message that refers the user to the Script Editor for more information.
New MRandom namespace
The new MRandom class provides interfaces to generate sequences of random numbers.
Unlike traditional PRNGs, which cannot be easily parallelized, this algorithm allows for parallelization as it does not require that n-1 be generated in order to generate n. It is very fast and passes statistical tests on randomness, and in addition, you can obtain the same result each time you call this function with the same arguments.
New methods for working with double precision meshes
MObject MFnMesh::create (int numVertices, int numPolygons, const MPointArray &vertexArray, const MIntArray &polygonCounts, const MIntArray &polygonConnects, bool storeDoubles, MObject parentOrOwner, MStatus * ReturnStatus)
The following functions have been added to the MFileObject class in both the C++ and Python API. Raw URI information can now be accessed via MPxFileResolver:
The following multiplication operator functions have been added:
The following new interfaces have been added to MPlug:
These methods are similar to the existing MPlug::connectedTo() method in that they produce the networked version of the connected plugs.
However, they offer the additional advantage that two of these methods: MPlug::source() and MPlug::destinations() allow you to ignore unit conversion nodes when making connection queries.
These methods are also supported in Python API 2.0.
Added the following functions to mute reference edits in a file reference node temporarily:
These methods are also supported in Python API 2.0.
This method is also supported in Python API 2.0.
Added the following functions to create a proxy attribute:
This method is also supported in Python API 2.0.
This method is also supported in Python API 2.0.
The new MPaintMessage class has been added that allows you to register callbacks for vertex color paining. See the paintCallback developer kit example for a demonstration of how to use this class.