The case of the disappearing particles


In this case, nParticles (render type = point) weren’t visible behind a refractive plane:
particles_not_visible

For the points render type, you get an Arnold points shape (with mode “disk”), so I exported an ASS file to see the parameter settings on the points node. I noticed the visibility 243 right away (the default visibility is 255, which is visible to all rays). And sure enough, in the Render Stats for the particle shape, some rays were turned off (and the check boxes were disabled too).
particles_render_stats

I used the User Options to force the visibility to 255
particles_useroptions
and the particles behind the refractive surface appeared:
particles_visible

This is a Maya thing. For most particle render types, the particles are not visible in reflections or refractions. It says so in the docs:

You can turn on reflections, refractions, and shadows when you software render Clouds, Tubes, and Blobby Surfaces

I’m not sure where the default values are set, but I did find the AEtemplate code that disables the render stats for all particle render types except the “s/w” type:

// C:\Program Files\Autodesk\Maya2015\scripts\AETemplates\AEparticleLayout.mel
		if( $value == 7 || $value == 8 || $value == 9 ) {
			// software particle type
			editorTemplate -dimControl $nodeName "visibleInReflections" false;
			editorTemplate -dimControl $nodeName "visibleInRefractions" false;
			editorTemplate -dimControl $nodeName "castsShadows"    		false;
			editorTemplate -dimControl $nodeName "receiveShadows" 		false;
			editorTemplate -dimControl $nodeName "primaryVisibility" 	false;
		} else {
			// hardware particle type
			editorTemplate -dimControl $nodeName "visibleInReflections" true;
			editorTemplate -dimControl $nodeName "visibleInRefractions" true;
			editorTemplate -dimControl $nodeName "castsShadows"			true;
			editorTemplate -dimControl $nodeName "receiveShadows" 		true;
			editorTemplate -dimControl $nodeName "primaryVisibility" 	true;
		}

So, since that AE template code just enables and disables UI controls, but doesn’t change the actual values, another way to enable Visible in Refractions (or Visible in Reflections) is to do this:

  1. Change the Particle Render Type to one of the “s/w” types, like Blobby Surface.
  2. Now the Visible in Refractions check box is enabled.
  3. Select the check box.
  4. Go back and change the Particle Render Type to points.

Now when you render, the points are visible to refraction rays, so they show up behind the glass.

The case of the “cannot remove alias” RuntimeError


In this case, mayabatch reported some runtime errors when loading a certain scene:

# Traceback (most recent call last):
#   File "C:\solidangle\mtoadeploy\2015\scripts\mtoa\callbacks.py", line 415, in deferredCallback
#     func(*args, **kwargs)
#   File "C:\solidangle\mtoadeploy\2015\scripts\mtoa\aovs.py", line 471, in createAliases
#     pm.aliasAttr(sg + '.ai_aov_' + name, remove=True)
#   File "C:\Program Files\Autodesk\maya2015\Python\lib\site-packages\pymel\internal\pmcmds.py", line 134, in wrappedCmd
#     res = new_cmd(*new_args, **new_kwargs)
# # RuntimeError: 'aiStandardSG.ai_aov_direct_specular' is not a unique name.  Cannot remove alias.

Now, even though I have the advantage of access to the MtoA source code, the problem remained: how do I fix the scene and stop these errors? To find a solution (and understand the problem) I had to resort to examining the Maya ASCII version of the scene.

The “fix” was to clear the AOV names on the shadingEngine node:

setAttr "aiStandardSG.aovs[0].aov_name" -type "string" ""; 
setAttr "aiStandardSG.aovs[1].aov_name" -type "string" ""; 
setAttr "aiStandardSG.aovs[2].aov_name" -type "string" ""; 

The problem is that the shadingEngine node has some named custom AOVs, but no corresponding “attribute alias” list. So the AOV name couldn’t be found in the alias list, which in the error message came out as “not a unique name”.

In the Maya ASCII version of the problem scene, I saw this:

createNode shadingEngine -n "aiStandardSG"; 
	addAttr -ci true -h true -sn "aal" -ln "attributeAliasList" -dt "attributeAlias"; 
	setAttr -s 4 ".aovs"; 
	setAttr ".aovs[0].aov_name" -type "string" "direct_diffuse";
	setAttr ".aovs[1].aov_name" -type "string" "direct_specular";
	setAttr ".aovs[2].aov_name" -type "string" "indirect_diffuse";
	setAttr ".aovs[3].aov_name" -type "string" "indirect_specular";

instead of this:

createNode shadingEngine -n "aiStandard1SG";
	addAttr -ci true -h true -sn "aal" -ln "attributeAliasList" -dt "attributeAlias";
	setAttr ".ihi" 0;
	setAttr ".ro" yes;
	setAttr -s 4 ".aovs";
	setAttr ".aovs[0].aov_name" -type "string" "direct_diffuse";
	setAttr ".aovs[1].aov_name" -type "string" "direct_specular";
	setAttr ".aovs[2].aov_name" -type "string" "indirect_diffuse";
	setAttr ".aovs[3].aov_name" -type "string" "indirect_specular";
	setAttr ".aal" -type "attributeAlias" {"ai_aov_direct_diffuse","aiCustomAOVs[0]",
			"ai_aov_direct_specular","aiCustomAOVs[1]",
			"ai_aov_indirect_diffuse","aiCustomAOVs[2]",
			"ai_aov_indirect_specular","aiCustomAOVs[3]"} ;

I don’t know how the user managed to get the scene into that state 😉

The case of the missing PyMel debug log file


In several recent cases, I had to figure out why MtoA wouldn’t load on a render farm. The root cause turned out to be the PyMel debug log: ~/pymel.log

If PyMel cannot find or open ~/pymel.log, that stops PyMel and anything that uses PyMel (like MtoA).

On a render farm, this can happen if the render manager user account doesn’t have a home folder, ~/pymel.log doesn’t expand to a valid location, or if user doesn’t have read-write permissions on pymel.log.

For example, here’s the Process Monitor log when ~ cannot be resolved:
pymel.log.2
And here’s the log when the user doesn’t have read-write permissions:
pymel.log
The location of pymel.log is specified by the pymel.conf configuration file, like this:

os.path.expanduser('~/pymel.log')

When there’s a problem with the PyMel debug log, it can be hard to tell from the MtoA errors. You may see API errors like this (but the line numbers all point to unrelated bits of source code). However, if you see these line numbers with the MtoA 1.x, it’s probably a pymel.log problem.

API error detected in plugins\mtoa\Main.cpp at line 794
: (kFailure): Unexpected Internal Failure
00:00:00   514MB ERROR   | Failed to register renderer 'arnold'

API error detected in plugins\mtoa\Main.cpp at line 716
: (kFailure): Unexpected Internal Failure
00:00:00   514MB ERROR   | Failed to register Arnold swatch renderer

API error detected in plugins\mtoa\Main.cpp at line 716
: (kFailure): Unexpected Internal Failure
00:00:00   515MB ERROR   | Failed to register Arnold swatch renderer

You might also see errors like this:

API error detected in plugins/mtoa/Main.cpp at line 794
: (kFailure): Unexpected Internal Failure
Error: line 1: IOError: file /Applications/Autodesk/maya2015/Maya.app/Contents/Frameworks/Python.framework/Versions/Current/lib/python2.7/logging/__init__.py line 916: 13
Error: line 1: Failed to register renderer 'arnold'
Error: line 1: initializePlugin function failed (mtoa)

[MtoA] The case of the instant crash when I load MtoA


In this case, Maya 2015 (Windows) disappeared a few seconds after I clicked the MtoA Loaded check box in the Plug-in Manager. Eventually I tracked it down to this line in my pluginPrefs.mel:

evalDeferred("autoLoadPlugin(\"\", \"PolyTools\", \"PolyTools\")");

Darn you PolyTools, I forgot about you 😉 There’s some kind of conflict between PolyTools (from the Maya BonusTools) and MtoA.

I tracked this down the hard way, by renaming my 2015 MAYA_APP_DIR to 2015-x64.bak and starting over with the default preferences, and then comparing the two.

An easier way (on Windows) would have been to use MTOA_STARTUP_LOG_VERBOSITY along with the -log command-line flag (for example, maya -log %TEMP%\mayastartup.log), which would have given me this:

****
* Arnold 4.2.4.0.wip windows icc-13.1.3 oiio-1.4.14 rlm-11.1.2 2015/01/23 16:50:01
* CRASHED in Tstring::formatToWidth at 00:00:00, pixel (0, 0)
* signal caught: error C0000005 -- access violation
*
* backtrace:
*  0 0x0000000045476700 [ai            ] AiArray                                                                                                                                                                               
*  1 0x0000000045477eff [ai            ] AiArray                                                                                                                                                                               
*  2 0x00000000773cb940 [kernel32      ] UnhandledExceptionFilter                                                                                                                                                              
*  3 0x00000000774e3398 [ntdll         ] MD5Final                                                                                                                                                                              
*  4 0x00000000774685c8 [ntdll         ] _C_specific_handler                                                                                                                                                                   
*  5 0x0000000077479d2d [ntdll         ] RtlDecodePointer                                                                                                                                                                      
*  6 0x00000000774691cf [ntdll         ] RtlUnwindEx                                                                                                                                                                           
*  7 0x00000000774a1248 [ntdll         ] KiUserExceptionDispatcher                                                                                                                                                             
>> 8 0x000007fee46eeb05 [FOUNDATION    ] Tstring::formatToWidth                                                                                                                                                                
*  9 0x000007fee46efff5 [FOUNDATION    ] Tstring::set                                                                                                                                                                          
* 10 0x000007febe593e9c [PolyTools     ] uninitializePlugin                                                                                                                                                                    
* 11 0x000007febe593feb [PolyTools     ] uninitializePlugin                   
...

[MtoA] Mapping textures to Yeti hair


Like MtoA, Yeti exports UV coordinates in the uparamcoord and vparamcoord parameters, and you use these to map textures in the aiHair shader with the Uparam and Vparam extra attributes.
yet_uv_3

For example, if you plug a texture into the Rootcolor and tipcolor
yet_uv_2
then you can use uparamcoord and vparamcoord to map that texture onto the hair:
yet_uv_1

Tip If you enable Expand Procedurals and export an ASS file, you can see what parametes Yeti exports:

### created by pgYetiMayaShape
curves
{
 name pgYetiMayaShape_|pgYetiMaya|pgYetiMayaShape|scatter01_pSphereShape1_grow01
 num_points 621 1 b85UINT
# ...
 points 4347 1 b85POINT
# ...
 basis "catmull-rom"
 mode "ribbon"
 min_pixel_width 0
 visibility 255
 self_shadows on
 matrix
 1 0 0 0
 0 1 0 0
 0 0 1 0
 0 0 0 1
 shader "initialShadingGroup"
 opaque on
 id -1230660816
 declare curve_id uniform UINT
 curve_id 621 1 b85UINT
# ...
 declare uparamcoord uniform FLOAT
 uparamcoord 621 1 b85FLOAT
# ...
 declare vparamcoord uniform FLOAT
 vparamcoord 621 1 b85FLOAT
# ...
 declare surf_s uniform FLOAT
 surf_s 621 1 b85FLOAT
# ...
 declare surf_t uniform FLOAT
 surf_t 621 1 b85FLOAT
# ...
 declare length uniform FLOAT
 length 621 1 b85FLOAT
# ...
 declare fur_id uniform FLOAT
 fur_id 621 1 b85FLOAT
# ...
 declare surf_n uniform VECTOR
 surf_n 621 1 b85VECTOR
# ...
 declare filename constant STRING
 filename "C:/Users/StephenBlair/Documents/maya/projects/Support//yeti/tmp/yeti_combExample_pgYetiMayaShape_1886244453_1.fur"
 declare mtoa_shading_groups constant ARRAY NODE
 mtoa_shading_groups "initialShadingGroup"
 declare frame constant INT
 frame 1
 declare verbosity constant INT
 verbosity 1
 declare density constant FLOAT
 density 10
 declare width constant FLOAT
 width 1
 declare threads constant INT
 threads 0
 declare min_pixel_width constant FLOAT
 min_pixel_width 0
 declare mode constant INT
 mode 0
 declare imageSearchPath constant STRING
 imageSearchPath ""
 declare samples constant ARRAY FLOAT
 samples 1
}

[MtoA] Command-line compiling with Visual Studio 2010 Express


  1. Open a Visual Studio Command Prompt (Start > All Programs > Microsoft Visual Studio 2010 Express > Visual Studio Command Prompt)
  2. Set up the environment for 64-bit compilation:

    CALL "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64 /Release
    

And now you’re ready to go. For example, if you were following the basic extensions tutorial, you set some environment variables:

set ARNOLD_PATH=C:\solidangle\arnold\Arnold-4.2.2.0-windows
set MTOA_PATH=C:\solidangle\mtoadeploy\2014
set MAYA_PATH="C:\Program Files\Autodesk\Maya2014"

Note that we included the quotation marks in MAYA_PATH, since the path includes an embedded space. An alternative would be to use the quotation marks in the cl and link commands.

cl /c translator1.cpp /EHsc /MD /DNT_PLUGIN /DREQUIRE_IOSTREAM /I%MAYA_PATH%\include /I%MTOA_PATH%\include /I%ARNOLD_PATH%\include
cl /c extension1.cpp /EHsc /MD /DNT_PLUGIN /DREQUIRE_IOSTREAM /I%MAYA_PATH%\include /I%MTOA_PATH%\include /I%ARNOLD_PATH%\include
link /dll extension1.obj translator1.obj /LIBPATH:%ARNOLD_PATH%\lib /LIBPATH:%MAYA_PATH%\lib /LIBPATH:%MTOA_PATH%\lib ai.lib OpenGl32.lib glu32.lib Foundation.lib OpenMaya.lib OpenMayaRender.lib OpenMayaUI.lib OpenMayaAnim.lib OpenMayaFX.lib mtoa_api.lib

[MtoA] [MacOSX] Rendering a sequence


Here’s a question submitted through solidangle.com: how do I render a sequence of frames with Maya on Mac OS X?

The answer is: the same way you would a sequence of frames with mental ray in Maya.

In Maya:

From the command line:

  • Open a Maya Terminal, either through Spotlight or in Finder (/Applications/Autodesk/maya2015/Maya Terminal.term)

    Using a Maya Terminal means that the PATH already includes the location of the Maya command-line renderer.

  • In the terminal, use the Render command to render the sequence. For example:
    Render -r arnold -s 1 -e 10 -proj /Users/stephen/MyProject /Users/stephen/MyProject/scenes/arnold.mb
    

If Arnold is the renderer specified in the saved scene file, you can omit -r arnold from the Render command.

Run the command Render -help -r arnold to print the help for the Arnold-specific render flags.

[MtoA] Pimping your Yeti module file


Here’s a variation of the Yeti module file that adds the bin folder to the PATH, and plug-ins to MTOA_EXTENSIONS_PATH:

+ pgYetiMaya any C:\solidangle\yeti\Yeti-v1.3.14_Maya2014-windows64
PATH +:= bin
MTOA_EXTENSIONS_PATH +:= plug-ins

MtoA uses MTOA_EXTENSIONS_PATH to find the Yeti extension for MtoA, and Arnold uses PATH to find the Yeti procedural.

[MtoA] One mtoa.mod to rule them all


After a few tries, I got one mtoa.mod file that works for multiple Maya versions:

+ MAYAVERSION:2015 mtoa any C:\solidangle\mtoadeploy\2015
PATH +:= bin
+ MAYAVERSION:2014 mtoa any C:\solidangle\mtoadeploy\2014
PATH +:= bin
+ MAYAVERSION:2013 mtoa any C:\solidangle\mtoadeploy\2013
PATH +:= bin

I had to repeat the PATH line for each module, otherwise the bin folder wasn’t added to the PATH.

I just had to set MAYA_MODULE_PATH to point to this mtoa.mod file, and then I could load MtoA in Maya 2013, 2014, and 2015.

This could be useful if you have multiple users sharing a single machine, because with this mtoa.mod, you don’t have to worry about putting version-specific mtoa.mod files in every user’s Maya folder (by default, the MtoA installer puts mtoa.mod in the user’s $MAYA_APP_DIR\\modules\\<version> folders).

Another way to do it would to be put the mtoa.mod files in the default shared modules folders. For example, on Windows:

C:\Program Files\Common Files\Autodesk Shared\Modules\Maya\2013
C:\Program Files\Common Files\Autodesk Shared\Modules\Maya\2014
C:\Program Files\Common Files\Autodesk Shared\Modules\Maya\2015

On Linux:

/usr/autodesk/modules/maya/<version>

On Mac OS X:

/Users/Shared/Autodesk/maya/<version> for MacOS

[MtoA] Scripting Standin paths


standin_path

To set a standin path, use the aiStandin.dso attribute:

import maya.cmds as cmds
cmds.setAttr( 'ArnoldStandInShape.dso','C:/Users/SOLIDANGLE/Documents/BlueDog.ass',  type='string' )
print cmds.getAttr( 'ArnoldStandInShape.dso' )

Here’s one way to list some of the attributes on a standin shape node, and find out what attribute to set:

import maya.cmds as cmds
ntype = cmds.nodeType( "ArnoldStandInShape" )
print cmds.attributeInfo( inherited=False, t=ntype )

for x in cmds.attributeInfo( inherited=False, t=ntype ):
    print "%s = %s" % (x, cmds.getAttr( "ArnoldStandInShape.%s" % x ))