![]()
API and Devkit limitations
The following lists limitations and workarounds for the API and Devkit for Maya 8.5. We also recommend that you read the API guide documentation before attempting a major project using Maya.
It is not possible to distinguish between the color black and an unassigned color in an MPxHwShaderNode plug-in
There currently is no way of setting what value to use for an unassigned color of an
MPxHwShaderNodeplug-in. Currently, the color black or 0,0,0,1 is used as the unassigned color.Unable to unload an MPxNode plug-in if MPxData is specified
If a MPxNode plug-in creates an MPxData in its
initialize()method, you will receive a warning that the plug-in is in use when trying to unload it even if you have not created a node. This is because the proxy MPxData type is in use.Workaround
Do not create the
MPxDatauntil it is required in thecompute()method.MItMeshPolygon::getColors(colorArray) does not provide access to all colors
There is a second parameter to the
MItMeshPolygon::getColors()method. This parameter specifies the list of color sets that should be considered in the method. If not specified, this method will operate on the current color set.Workaround
Specify the list of color sets that should be considered by the
MItMeshPolygon::getColors()method.Plugs are deleted upon deleting or disconnecting nodes
When deleting or disconnecting nodes that are connected to other nodes, the plugs that are connected to the deleted or disconnected nodes gets deleted as well.
Workaround
Create a new plug for every attribute.
Attribute changed callbacks limitation
Attribute changed callbacks are not invoked if the modification to the attribute is made by a tool such as Move.
MFnDependencyNode flags limitation
MFnDependencyNode flags are not reset when they are deallocated. Resetting these flags requires an entire DG traversal.
For best performance, it is better for you to control this operation since you may only be interested in a subset of the depend nodes in the scene.
MFnMesh::assignUVs() does not support history
The method
MFnMesh::assignUVs()does not support history. As a result, modifications made to UVs with this method may be overwritten as the dependency graph updates.Long names of attributes can be incorrectly re-used
It is possible to create new attributes on a node that have the same long name as an already existing attribute but differs by the short name. This will cause updating problems for the Channel Box and Attribute Editor.API plugs and dependencies hierarchy limitation
The API does not support hierarchies of plugs and their dependencies in a single dependency node. Dirty propagation works correctly across connections between nodes, but not between internal attributes on a user-defined node made with
MPxNode.Workaround
Use the method
attributeAffects()to “flatten hierarchies” when declaring their affects behavior between all inputs and outputs on your node.OBJ files need “.obj” extension
Wavefront OBJ files need the .obj extension to be recognized automatically when the File > Open Scene Import option is set to Best Guess.
Workaround
Set the Import option to OBJ to import a file without the .obj extension.
Batch rendering scenes with plug-ins
If you have a Maya scene that uses two (or more) plug-ins, both of which fail in their “initializePlugin” method (due to a missing license for example), and both plug-ins require one of the libraries
OpenMayaUI,OpenMayaAnimorOpenMayaFX, when attempting to batch render the scene Maya may produce a fatal error.Workaround
Manually add the following lines at the end of your userPrefs.mel file.
Unloading and reloading plug-in
If a plug-in command is called from an expression or a MEL procedure, and after the expression or procedure has been parsed, the plug-in is unloaded (or unloaded and then reloaded), Maya may produce a fatal error if the expression is triggered or the procedure is re-executed. When MEL parses the expression or procedure, it saves a pointer to the doIt method of the plug-in command. The value of this pointer is not normally recalculated, so if the plug-in is unloaded or reloaded at a different location, the pointer is no longer valid.
Similar issues will occur if
MFnPlugin::registerUI()is used to register a command defined by a plug-in.Workaround
Enclose the call to the plug-in command in a MEL eval statement. This forces MEL to compile the statement each time the expression is evaluated or the procedure is run. If the plug-in has been unloaded this is detected and an error results. If the plug-in has been reloaded, the new location of the doIt method is computed during the recompile.
Custom material shader plug-in with a glow intensity attribute
If a custom material shader plug-in is implemented with a glow intensity attribute, this attribute will be ignored by the software renderer unless an internal Maya material shader in the scene (e.g. lambert, blinn, phong) has a glowIntensity value greater than zero. Currently the software renderer only queries material shader nodes that match the internal types for a
glowIntensityvalue that is greater than zero. There is no way to directly override this limitation.Workaround
In order to assure the rendering of a custom shader's
glowIntensityattribute anMSceneMessage::kBeforeSoftwareRendercallback and anMSceneMessge::kAfterSoftwareRendercallback must be registered. The first callback must create an internal material shader node via “shadingNode -asShader lambert;” and it must retrieve the node name returned. Then it must set that node's glowIntensity attribute to a value greater than zero. The second callback will simply remove this “dummy” node.Connecting the plugs of two nodes and breaking the connection
There may be situations in which it is desirable to connect the plugs of two nodes and then soon after break this connection. If
MDGModifier::connect()is used to connect geometry data between two nodes and if this connection is broken before the screen is refreshed the data will not be cached on the downstream node.Workaround
A call to
M3dView::active3dView().refresh();
before disconnecting the plugs will force the dependency graph to evaluate. This will cause the downstream geometry node to read the input data, and after this evaluation the data is available for caching to the node if the connection is subsequently broken.
Incomplete MPlugs
The plug passed to the user defined method that is registered with
MNodeMessage::addAttributeAddedOrRemovedCallback()is an incompleteMPlug. Complex data type values will not be accessible via MPlug::getValue(MObject value).Workaround
This problem can be circumvented by using code similar to the following.
MFnDependencyNode fnDn(plug.node()); /*where "plug" is the name of the plug passed in as a parameter */ MString newPlugName(plug.name()); /* MPlug::name() will actually return a string containing the "nodeName.attributeName" so it may need to be parsed for the following call. */ MPlug realPlug = fnDn.findPlug(newPlugName);In the above example, “realPlug” is a fully functional and accessible MPlug.
Custom nodes with store-able internal attributes that are arrays
Custom nodes with store-able internal attributes that are arrays may display incorrect array indices when they are read into Maya from a scene file containing the node. This will be apparent in the
MPxNode::setInternalValue()method if the number of array elements is compared to the plug's logical index and they are found to be equal in value. It is important to note that this will occur only with internal attributes.Type of MObject that Maya passes
The type of
MObjectthat Maya passes to the following methods will always beMFn::kInvalid.virtual MPxGeometryIterator * iterator (MObjectArray & componentList, MObject & component, bool useComponents) virtual MPxGeometryIterator * iterator (MObjectArray & componentList, MObject & component, bool useComponents, bool world) constThese routines are used in classes derived from MPxGeometryData. There is currently no workaround for this problem.
No hooks for creating light shader nodes
There are currently no hooks from within the API for creating light shader nodes with properties similar to Maya's area light node.
Creating a blendShape
If a blendShape is created from within the API using
MFnBlendShapeDeformer::create(), the methodMFnBlendShapeDeformer::addBaseObject()will fail if used with theMObjectof a curve that was newly created usingMFnNurbsCurve::create().Workaround
A simple workaround is to locate the
MDagPathof the newly created NURBS curve and obtain theMObjectfrom that class. This object can be used successfully withaddBaseObject().Tools performing “add pick”
Tools made with MPxSelectionContext perform an “add pick” by default as opposed to the built in Maya selection tools which perform a “replace pick” by default. An “add pick” adds a selection to the active selection list while a “replace pick” replaces the current selection list with the selected object or objects.
Workaround
Use
MGlobal::displayInfo()to instruct the user to left click the mouse in an empty part of the scene in order to begin a new selection.Method setCursor()
When the method
setCursor()is called with an instance of anMPxSelectionContextclass the method will fail. The same method called with an instance ofMPxContextwill function as documented.Method MDrawRequestQueue::isEmpty()
Using the method MDrawRequestQueue::isEmpty() on an instance of MDrawRequestQueue to which no
MDrawRequestshave been added will cause Maya to crash.Workaround
The method operates as documented if called on a queue to which one or more
MDrawRequestshave been added. Incorporate state checking code to assure that an MDrawRequest has been appended before make a call toisEmpty().Assigning a texture shader as an input to a built-in Maya material shader
When a user assigns a texture shader as an input to a built-in Maya material shader (for example, lambert) a connection is automatically made between the texture node's message attribute and the downstream materialInfo node's texture[0] attribute. This is necessary for accurate hardware rendering. This does not happen automatically with custom material shaders and procedures will have to be implemented to make the connection. Unfortunately when the scene is saved and re-opened the texture will no longer be connected to the materialInfo node's texture[0] attribute. Instead the material shader's message attribute will have this connection.
Workaround
Procedures will have to be implemented to break this connection and reconnect the texture node's message attribute with the texture[0] attribute. Possible solutions may include: the registering of a callback in the plug-in's initialize method to check for this connection and alter it if necessary, or the modification of the AE template script to make such connections when necessary.
Monitoring the desired hardware resolution of a Texture2d node
To monitor the desired hardware resolution of a Texture2d node the renderer queries its resolution attribute. This attribute is added dynamically to a texture when the user sets the Hardware Texturing >Texture Quality of a built in material shader node (e.g. lambert.). This is not the case with custom material shader plug-ins.
Workaround
A procedure must be implemented that will dynamically add the resolution attribute (type kLong) to an input texture. The resolution attribute can have the values: 32, 64, 128, or 256.
MPxContext::doHold() method
The
MPxContext::doHold()method is called on a context tool even if thekey is pressed. Ordinarily the use of the
key should override the context tool and allow exclusive use of the tumble mechanism. Instead, both happen simultaneously.
Shader plug-ins and using float2 compound attributes
Shader plug-ins that make use of
float2compound attributes may occasionally receive incorrect data from the data block.Workaround
It is best to extract the data as a compound attribute, and retrieve the contents individually. In other words, the first example is preferred over the second equivalent example.
float2& uv = block.inputValue( aUVCoord ).asFloat2(); float u = uv[0]; float v = uv[1]; vs. float& u = block.inputValue( aUCoord ).asFloat(); float& v = block.inputValue( aVCoord ).asFloat();Coding it the second way may result in the u and v values being the same in certain cases.
Calling MFnMesh::deleteFace()
A call to
MFnMesh::deleteFace()will insert a deleteComponent node as construction history upstream from the affected mesh, however a call toMFnMesh::addPolygon()does not insert a corresponding construction history node.Workaround
MFnMesh::addPolygon()should only be used from within the compute method of a node that is placed upstream from the affected mesh object. Within the compute method theMFnMeshinstance will act upon thekMeshDatathat is passed through as input and output data.Querying the active view port within the API
There is no way within the API to query the active view port to find out if textures are currently displayed, nor is it possible to set this option.
MPxCommand and complex data types
When writing an
MPxCommandthat is intended to receive arguments from the MEL command line, please be aware that there is no way to hand a command plug-in a complex data type by pointer value.Workaround
The class MArgList contains several methods that permit the passing of complex data types from the MEL command line to a plug-in command. These are:
MStatus get( unsigned& indexReadAndUpdate, MVector&, unsigned numElements=3 ) const MStatus get( unsigned& indexReadAndUpdate, MPoint&, unsigned numElements=3 ) const MStatus get( unsigned& indexReadAndUpdate, MMatrix& ) const MStatus get( unsigned& indexReadAndUpdate, MIntArray& ) const MStatus get( unsigned& indexReadAndUpdate, MDoubleArray& ) const MStatus get( unsigned& indexReadAndUpdate, MStringArray& ) constMFnPluginData::create() will fail to maintain a reference to an MObject
MFnPluginData::create()will fail to maintain a reference to anMObjectif the assignment is not done at the time of creation. For example this will fail:Workaround
Always assign the
MObjectat the time of creation so that a reference will be maintained internally. For example:MFnFreePointTriadManipulator::setSnapMode(false)
If
MFnFreePointTriadManipulator::setSnapMode(false)is set to false, it will remain in snapMode if a single axis handle is manipulated. If the central handle is used the manipulator will move freely.Global selection list does not preserve selection order of mesh object components
The global selection list does not preserve selection order of mesh object components. For example, a tool designed to operate selected mesh vertices should not depend on the selection order.
MItDependencyGraph only traverses connections that affect the specified starting plug or node
MItDependencyGraphonly traverses connections that affect the specified starting plug or node. Therefore, it may not traverse some connected nodes, such as connections to message attributes or dynamic attributes. Also, connections to a transform node's translate, rotate, scale attributes will not be found if traversing upstream through the worldMatrix output. Additionally, sinceAnimUtil::isAnimated()relies onMItDependencyGraphfor its functionality, it will not find animCurves connected to the translate, rotate or scale if getting there requires traversing the transform node's worldMatrix attribute.Workaround
When using
MItDependencyGraph, when a transform node or message plug is reached, prune the current iteration and start anotherMItDependencyGraph. When usingMAnimUtil::isAnimated(), when a transform node or message plug is reached, callMAnimUtil::isAnimated()again.Invoking the objExists MEL command limitation
Invoking the objExists MEL command with MGlobal::executeCommand() during the retrieval of a scene file can produce incorrect results.
MArgDatabase::getFlagArgument() and MArgParser::getFlagArgument() usage limitation
The methods MArgDatabase::getFlagArgument() and MArgParser::getFlagArgument() require that numbers larger than 2^31 be enclosed in quotes.
MPxSurfaceShape related problems
The following lists MPXSurfaceShape related problems.
User defined shapes created with MPxSurfaceShape
User defined shapes created with
MPxSurfaceShapecannot support per-components texturing or shading.